Completed
Push — master ( b7d6fa...54f51b )
by Ryuichi
02:48
created

ExceptionDelegator::raise()   D

Complexity

Conditions 10
Paths 40

Size

Total Lines 35
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 10.0094

Importance

Changes 0
Metric Value
dl 0
loc 35
ccs 21
cts 22
cp 0.9545
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 22
nc 40
nop 0
crap 10.0094

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
class ExceptionDelegator
9
{
10
    use Injector;
11
12
    /**
13
     * @var Logger ロガー
14
     */
15
    private $logger;
16
17
    /**
18
     * @var object インスタンス
19
     */
20
    private $instance;
21
22
    /**
23
     * @var string メソッド名
24
     */
25
    private $method;
26
27
    /**
28
     * @var \Exception 例外オブジェクト
29
     */
30
    private $exceptionObject;
31
32
    /**
33
     * @var array<Container> 例外ハンドリングリスト
34
     */
35
    private $exceptionHandler;
36
37
    /**
38
     * constructor
39
     */
40 8
    public function __construct($instance, \Exception $exceptionObject, string $method = null)
41
    {
42 8
        $this->instance = $instance;
43 8
        $this->method = $method;
44 8
        $this->exceptionObject = $exceptionObject;
45 8
        $this->exceptionHandler = [];
46
        $this->logger = new class() { function __call($name, $args) {} };
0 ignored issues
show
Documentation Bug introduced by
It seems like new class { function...e, $args) { } } of type object<WebStream\Excepti...ceptionDelegator.php$0> is incompatible with the declared type object<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...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

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