Completed
Branch master (91c650)
by Ryuichi
05:32 queued 02:45
created

ExceptionDelegator::raise()   D

Complexity

Conditions 10
Paths 40

Size

Total Lines 35
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 22
nc 40
nop 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 ロガー
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 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...
53
    }
54
55
    /**
56
     * 例外ハンドリングリストを設定する
57
     * @param array<Container> 例外ハンドリングリスト
58
     */
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