Passed
Push — master ( 51dcfe...4ee661 )
by Ryuichi
02:30
created

ExceptionDelegator.php$0 ➔ raise()   F

Complexity

Conditions 10

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
dl 0
loc 34
rs 3.1304
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace WebStream\Exception\Delegate;
3
4
use WebStream\DI\Injector;
5
use WebStream\Exception\SystemException;
6
use WebStream\Exception\DelegateException;
7
8
/**
9
 * ExceptionDelegator
10
 * @author Ryuichi TANAKA.
11
 * @since 2014/05/05
12
 * @version 0.7
13
 */
14
class ExceptionDelegator
15
{
16
    use Injector;
17
18
    /**
19
     * @var Logger ロガー
0 ignored issues
show
Bug introduced by
The type WebStream\Exception\Delegate\Logger was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
     */
21
    private $logger;
22
23
    /**
24
     * @var object インスタンス
25
     */
26
    private $instance;
27
28
    /**
29
     * @var string メソッド名
30
     */
31
    private $method;
32
33
    /**
34
     * @var \Exception 例外オブジェクト
35
     */
36
    private $exceptionObject;
37
38
    /**
39
     * @var array<Container> 例外ハンドリングリスト
40
     */
41
    private $exceptionHandler;
42
43
    /**
44
     * constructor
45
     */
46
    public function __construct($instance, \Exception $exceptionObject, string $method = null)
47
    {
48
        $this->instance = $instance;
49
        $this->method = $method;
50
        $this->exceptionObject = $exceptionObject;
51
        $this->exceptionHandler = [];
52
        $this->logger = new class() { function __call($name, $args) {} };
0 ignored issues
show
Documentation Bug introduced by
It seems like new ClassNode() of type anonymous//Modules/Excep...xceptionDelegator.php$0 is incompatible with the declared type WebStream\Exception\Delegate\Logger of property $logger.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
53
    }
54
55
    /**
56
     * 例外ハンドリングリストを設定する
57
     * @param array<Container> 例外ハンドリングリスト
58
     */
0 ignored issues
show
Documentation Bug introduced by
The doc comment 例外ハンドリングリスト at position 0 could not be parsed: Unknown type name '例外ハンドリングリスト' at position 0 in 例外ハンドリングリスト.
Loading history...
59
    public function setExceptionHandler(array $exceptionHandler)
60
    {
61
        $this->exceptionHandler = $exceptionHandler;
62
    }
63
64
    /**
65
     * 例外を実行する
66
     */
67
    public function raise()
68
    {
69
        $originException = $this->exceptionObject;
70
        $delegateException = null;
71
        if ($originException instanceof DelegateException) {
72
            // 複数レイヤ間で例外がやりとりされる場合、すでにDelegateExceptionでラップ済みなので戻す
73
            $originException = $originException->getOriginException();
74
        }
75
        $invokeMethods = [];
76
        foreach ($this->exceptionHandler as $exceptionHandlerAnnotation) {
77
            $exceptions = $exceptionHandlerAnnotation->exceptions;
78
            $refMethod = $exceptionHandlerAnnotation->method;
79
            foreach ($exceptions as $exception) {
80
                if (is_a($originException, is_object($exception) ? get_class($exception) : $exception)) {
81
                    // 一つのメソッドに複数の捕捉例外が指定された場合(派生例外クラス含む)、先勝で1回のみ実行する
82
                    // そうでなければ複数回メソッドが実行されるため
83
                    // ただし同一クラス内に限る(親クラスの同一名のメソッドは実行する)
84
                    $classpath = $refMethod->class . "#" . $refMethod->name;
85
                    if (!array_key_exists($classpath, $invokeMethods)) {
86
                        $invokeMethods[$classpath] = $refMethod;
87
                    }
88
                }
89
            }
90
        }
91
        if (count($invokeMethods) > 0) {
92
            $delegateException = new DelegateException($this->exceptionObject);
93
            $delegateException->enableHandled();
94
        }
95
        foreach ($invokeMethods as $classpath => $invokeMethod) {
96
            $params = ["class" => get_class($this->instance), "method" => $this->method, "exception" => $originException];
97
            $invokeMethod->invokeArgs($this->instance, [$params]);
98
            $this->logger->debug("Execution of handling is success: " . $classpath);
99
        }
100
        throw $delegateException ?: $originException;
101
    }
102
}
103