Passed
Push — master ( 550b9e...103607 )
by Sébastien
09:49 queued 07:35
created

DefaultThrowExceptionProxyFactory   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Test Coverage

Coverage 98.11%

Importance

Changes 0
Metric Value
eloc 59
dl 0
loc 128
ccs 52
cts 53
cp 0.9811
rs 10
c 0
b 0
f 0
wmc 11

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A checkResult() 0 4 1
B getExceptionFromResult() 0 68 8
A logException() 0 8 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Soluble\Japha\Bridge\Driver\Pjb62\Proxy;
6
7
use Psr\Log\LoggerInterface;
8
use Soluble\Japha\Bridge\Driver\Pjb62;
9
use Soluble\Japha\Bridge\Exception;
10
use Soluble\Japha\Bridge\Driver\Pjb62\Client;
11
12
class DefaultThrowExceptionProxyFactory extends Pjb62\ThrowExceptionProxyFactory
13
{
14
    /**
15
     * @var LoggerInterface
16
     */
17
    protected $logger;
18
19
    /**
20
     * @var string
21
     */
22
    protected $defaultException = 'JavaException';
23
24
    /**
25
     * @var array
26
     */
27
    protected $msgPatternsMapping = [
28
        'NoSuchMethodException' => '/(php.java.bridge.NoSuchProcedureException)|(Cause: java.lang.NoSuchMethodException)/',
29
        'ClassNotFoundException' => '/Cause: java.lang.ClassNotFoundException/',
30
        //'InvalidArgumentException' => '/^Invoke failed(.*)php.java.bridge.NoSuchProcedureException/',
31
        'SqlException' => '/^Invoke failed(.*)java.sql.SQLException/',
32
        'NoSuchFieldException' => '/Cause: java.lang.NoSuchFieldException/',
33
        //'NullPointerException' => '/Cause: java.lang.NullPointerException/'
34
    ];
35
36
    /**
37
     * @param Client          $client
38
     * @param LoggerInterface $logger
39
     */
40 23
    public function __construct(Client $client, LoggerInterface $logger)
41
    {
42 23
        parent::__construct($client);
43 23
        $this->logger = $logger;
44 23
    }
45
46
    /**
47
     * @param Pjb62\Exception\JavaException $result
48
     *
49
     * @throws Exception\JavaExceptionInterface
50
     */
51 16
    public function checkResult(Pjb62\Exception\JavaException $result): void
52
    {
53 16
        $exception = $this->getExceptionFromResult($result);
54 3
        throw $exception;
55
    }
56
57
    /**
58
     * @param Pjb62\Exception\JavaException $result
59
     *
60
     * @return Exception\JavaExceptionInterface
61
     */
62 16
    private function getExceptionFromResult(Pjb62\Exception\JavaException $result): Exception\JavaExceptionInterface
63
    {
64 16
        $message = $result->__get('message')->__toString();
65
66 16
        $found = false;
67
68 16
        foreach ($this->msgPatternsMapping as $exceptionClass => $pattern) {
69 16
            if (preg_match($pattern, $message)) {
70 13
                $found = true;
71 13
                break;
72
            }
73
        }
74
75 16
        if (!$found) {
76 3
            $exceptionClass = $this->defaultException;
77
        } else {
78 13
            $exceptionClass = '';
79
        }
80
81 16
        $cls = '\\Soluble\\Japha\\Bridge\\Exception\\'.$exceptionClass;
82
83 16
        $stackTrace = $result->getCause()->__toString();
0 ignored issues
show
Bug introduced by
The method getCause() does not exist on Soluble\Japha\Bridge\Dri...Exception\JavaException. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

83
        $stackTrace = $result->/** @scrutinizer ignore-call */ getCause()->__toString();
Loading history...
84 16
        $code = $result->getCode();
85
86 16
        $driverException = null;
87 16
        if ($result instanceof \Exception) {
0 ignored issues
show
introduced by
$result is always a sub-type of Exception.
Loading history...
88 16
            $driverException = $result;
89
        }
90
91
        // Public message, mask any login/passwords
92 16
        $message = preg_replace('/user=([^&\ ]+)|password=([^&\ ]+)/', '****', $message);
93
94
        // Getting original class name from cause
95 16
        $javaExceptionClass = 'Unkwown java exception';
96 16
        $cause = 'Unknown cause';
97
98 16
        if (is_string($message)) {
0 ignored issues
show
introduced by
The condition is_string($message) is always true.
Loading history...
99 16
            preg_match('/Cause: ([^:]+):/', $message, $matches);
100 16
            if (count($matches) > 1) {
101 16
                $javaExceptionClass = $matches[1];
102
            }
103
104
            // Getting cause from message
105 16
            $tmp = explode('Cause: ', $message);
106 16
            if (count($tmp) > 1) {
107 16
                array_shift($tmp);
108 16
                $cause = trim(implode(', ', $tmp));
109
            } else {
110 16
                $cause = $message;
111
            }
112
        } else {
113
            $message = 'Empty message';
114
        }
115
116
117 16
        $e = new $cls(
118 3
            $message,
119 3
            $cause,
120 3
            $stackTrace,
121 3
            $javaExceptionClass,
122 3
            $code,
123 3
            $driverException,
124 3
            null
125
        );
126
127 3
        $this->logException($e, $exceptionClass);
128
129 3
        return $e;
130
    }
131
132 3
    private function logException(\Throwable $e, string $exceptionClass): void
133
    {
134 3
        $this->logger->error(sprintf(
135 3
            '[soluble-japha] Encountered exception %s: %s, code %s (%s)',
136 3
            $exceptionClass,
137 3
            $e->getMessage(),
138 3
            $e->getCode() ?? '?',
139 3
            get_class($e)
140
        ));
141 3
    }
142
}
143