Passed
Push — feature/0.7.0 ( 0c7d59...ae5b22 )
by Ryuichi
78:01 queued 33:04
created

ExceptionDelegator   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 92
rs 10
c 0
b 0
f 0
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A setExceptionHandler() 0 3 1
F raise() 0 45 10
1
<?php
2
namespace WebStream\Delegate;
3
4
use WebStream\Core\CoreInterface;
5
use WebStream\Exception\SystemException;
6
use WebStream\Exception\DelegateException;
7
use WebStream\DI\Injector;
8
9
/**
10
 * ExceptionDelegator
11
 * @author Ryuichi TANAKA.
12
 * @since 2014/05/05
13
 * @version 0.7
14
 */
15
class ExceptionDelegator
16
{
17
    use Injector;
18
19
    /**
20
     * @var CoreInterface インスタンス
21
     */
22
    private $instance;
23
24
    /**
25
     * @var string メソッド名
26
     */
27
    private $method;
28
29
    /**
30
     * @var \Exception 例外オブジェクト
31
     */
32
    private $exceptionObject;
33
34
    /**
35
     * @var array<AnnotationContainer> 例外ハンドリングリスト
36
     */
37
    private $exceptionHandler;
38
39
    /**
40
     * constructor
41
     */
42
    public function __construct(CoreInterface $instance, \Exception $exceptionObject, $method = null)
43
    {
44
        $this->instance = $instance;
45
        $this->method = $method;
46
        $this->exceptionObject = $exceptionObject;
47
        $this->exceptionHandler = [];
48
    }
49
50
    /**
51
     * 例外ハンドリングリストを設定する
52
     * @param array<AnnotationContainer> 例外ハンドリングリスト
53
     */
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...
54
    public function setExceptionHandler(array $exceptionHandler)
55
    {
56
        $this->exceptionHandler = $exceptionHandler;
57
    }
58
59
    /**
60
     * 例外を実行する
61
     */
62
    public function raise()
63
    {
64
        // 捕捉可能な例外の場合のみDelegateExceptionでラップする
65
        // そうでない場合はそのままスロー
66
        if ($this->exceptionObject instanceof SystemException) {
67
            throw $this->exceptionObject;
68
        } else {
69
            $originException = $this->exceptionObject;
70
            $delegateException = null;
71
72
            if ($originException instanceof DelegateException) {
73
                // 複数レイヤ間で例外がやりとりされる場合、すでにDelegateExceptionでラップ済みなので戻す
74
                $originException = $delegateException->getOriginException();
0 ignored issues
show
Bug introduced by
The method getOriginException() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

74
                /** @scrutinizer ignore-call */ 
75
                $originException = $delegateException->getOriginException();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
75
            }
76
77
            $invokeMethods = [];
78
            foreach ($this->exceptionHandler as $exceptionHandlerAnnotation) {
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $exceptionHandlerAnnotation exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
79
                $exceptions = $exceptionHandlerAnnotation->exceptions;
80
                $refMethod = $exceptionHandlerAnnotation->method;
81
                foreach ($exceptions as $exception) {
82
                    if (is_a($originException, $exception)) {
83
                        // 一つのメソッドに複数の捕捉例外が指定された場合(派生例外クラス含む)、先勝で1回のみ実行する
84
                        // そうでなければ複数回メソッドが実行されるため
85
                        // ただし同一クラス内に限る(親クラスの同一名のメソッドは実行する)
86
                        // TODO ここはテストを追加する
87
                        $classpath = $refMethod->class . "#" . $refMethod->name;
88
                        if (!array_key_exists($classpath, $invokeMethods)) {
89
                            $invokeMethods[$classpath] = $refMethod;
90
                        }
91
                    }
92
                }
93
            }
94
95
            if (count($invokeMethods) > 0) {
96
                $delegateException = new DelegateException($this->exceptionObject);
97
                $delegateException->enableHandled();
98
            }
99
100
            foreach ($invokeMethods as $classpath => $invokeMethod) {
101
                $params = ["class" => get_class($this->instance), "method" => $this->method, "exception" => $originException];
102
                $invokeMethod->invokeArgs($this->instance, [$params]);
103
                $this->logger->debug("Execution of handling is success: " . $classpath);
0 ignored issues
show
Bug Best Practice introduced by
The property logger does not exist on WebStream\Delegate\ExceptionDelegator. Since you implemented __get, consider adding a @property annotation.
Loading history...
104
            }
105
106
            throw $delegateException ?: $originException;
107
        }
108
    }
109
}
110