Test Failed
Push — master ( 389090...91c650 )
by Ryuichi
02:53
created

ExceptionDelegator::setExceptionHandler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
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