Completed
Pull Request — develop (#3536)
by Jonathan
60:42
created

DBALException::wrapException()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 10
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 4
nc 3
nop 3
crap 20
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\DBAL;
6
7
use Doctrine\DBAL\Driver\DriverException as DriverExceptionInterface;
8
use Doctrine\DBAL\Driver\ExceptionConverterDriver;
9
use Doctrine\DBAL\Exception\DriverException;
10
use Exception;
11
use InvalidArgumentException;
12
use Throwable;
13
use function array_map;
14
use function bin2hex;
15
use function get_class;
16
use function get_resource_type;
17
use function gettype;
18
use function implode;
19
use function is_array;
20
use function is_bool;
21
use function is_object;
22
use function is_resource;
23
use function is_string;
24
use function json_encode;
25
use function preg_replace;
26
use function sprintf;
27
28
class DBALException extends Exception
29 3666
{
30
    /**
31 3666
     * @param string  $sql
32 3666
     * @param mixed[] $params
33 3255
     *
34
     * @return self
35 3666
     */
36
    public static function driverExceptionDuringQuery(Driver $driver, Throwable $driverEx, $sql, array $params = [])
37 3666
    {
38
        $messageFormat = <<<'MESSAGE'
39
An exception occurred while executing "%s"%s:
40
41
%s.
42
MESSAGE;
43 3121
44
        $message = sprintf(
45 3121
            $messageFormat,
46
            $sql,
47
            $params !== [] ? sprintf(' with params %s', self::formatParameters($params)) : '',
48
            $driverEx->getMessage()
49
        );
50
51 3672
        return static::wrapException($driver, $driverEx, $message);
52
    }
53 3672
54 3179
    /**
55
     * @return self
56 3670
     */
57 3656
    public static function driverException(Driver $driver, Throwable $driverEx)
58
    {
59
        return static::wrapException($driver, $driverEx, sprintf('An exception occurred in driver with message: %s', $driverEx->getMessage()));
60 3243
    }
61
62
    public static function formatValue($value) : string
63
    {
64
        if ($value === null) {
65
            return 'NULL';
66
        }
67
68
        if (is_object($value)) {
69
            return get_class($value);
70
        }
71 3255
72
        if (is_resource($value)) {
73
            return get_resource_type($value);
74 3255
        }
75 3204
76
        if (is_bool($value)) {
77
            return $value === true ? 'true' : 'false';
78 3253
        }
79
80 3253
        if (is_array($value)) {
81
            return self::formatParameters($value);
82 3229
        }
83
84
        if (is_string($value)) {
85 3253
            return $value;
86 3255
        }
87
88
        throw new InvalidArgumentException(sprintf('Could not format value of type "%s".', gettype($value)));
89
    }
90
91
    /**
92
     * @return self
93
     */
94
    private static function wrapException(Driver $driver, Throwable $driverEx, $msg)
95
    {
96
        if ($driverEx instanceof DriverException) {
97
            return $driverEx;
98
        }
99
        if ($driver instanceof ExceptionConverterDriver && $driverEx instanceof DriverExceptionInterface) {
100
            return $driver->convertException($msg, $driverEx);
101
        }
102
103
        return new self($msg, 0, $driverEx);
104
    }
105
106
    /**
107
     * Returns a human-readable representation of an array of parameters.
108
     * This properly handles binary data by returning a hex representation.
109
     *
110
     * @param mixed[] $params
111
     *
112
     * @return string
113
     */
114
    private static function formatParameters(array $params)
115
    {
116
        return '[' . implode(', ', array_map(static function ($param) {
117
            if (is_resource($param)) {
118
                return (string) $param;
119
            }
120
121
            $json = @json_encode($param);
122
123
            if (! is_string($json) || $json === 'null' && is_string($param)) {
0 ignored issues
show
introduced by
The condition is_string($json) is always true.
Loading history...
124
                // JSON encoding failed, this is not a UTF-8 string.
125
                return sprintf('"%s"', preg_replace('/.{2}/', '\\x$0', bin2hex($param)));
126
            }
127
128
            return $json;
129
        }, $params)) . ']';
130
    }
131
}
132