Skip to content

Commit 6af25fe

Browse files
committed
try/catch checking and converting of PDOException moved to drivers
1 parent 578dff6 commit 6af25fe

22 files changed

+169
-157
lines changed

src/Bridges/DatabaseTracy/ConnectionPanel.php

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use Nette;
1313
use Nette\Database\Connection;
14+
use Nette\Database\DriverException;
1415
use Nette\Database\Helpers;
1516
use Nette\Database\Result;
1617
use Tracy;
@@ -71,7 +72,7 @@ private function logQuery(Connection $connection, $result): void
7172

7273
$this->count++;
7374

74-
$trace = $result instanceof \PDOException
75+
$trace = $result instanceof DriverException
7576
? array_map(fn($row) => array_diff_key($row, ['args' => null]), $result->getTrace())
7677
: debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
7778

@@ -87,26 +88,20 @@ private function logQuery(Connection $connection, $result): void
8788
if ($this->count < $this->maxQueries) {
8889
$this->events[] = [$connection, $result->getQueryString(), $result->getParameters(), $trace, $result->getTime(), $result->getRowCount(), null];
8990
}
90-
} elseif ($result instanceof \PDOException && $this->count < $this->maxQueries) {
91-
$this->events[] = [$connection, $result->queryString, null, $trace, null, null, $result->getMessage()];
91+
} elseif ($result instanceof DriverException && $this->count < $this->maxQueries) {
92+
$this->events[] = [$connection, $result->getQueryString(), null, $trace, null, null, $result->getMessage()];
9293
}
9394
}
9495

9596

9697
public static function renderException(?\Throwable $e): ?array
9798
{
98-
if (!$e instanceof \PDOException) {
99+
if (!$e instanceof DriverException) {
99100
return null;
100101
}
101102

102-
if (isset($e->queryString)) {
103-
$sql = $e->queryString;
104-
105-
} elseif ($item = Tracy\Helpers::findTrace($e->getTrace(), 'PDO::prepare')) {
106-
$sql = $item['args'][0];
107-
}
108-
109-
return isset($sql) ? [
103+
$sql = $e->getQueryString();
104+
return $sql ? [
110105
'tab' => 'SQL',
111106
'panel' => Helpers::dumpSql($sql, $e->params ?? []),
112107
] : null;
@@ -144,7 +139,7 @@ public function getPanel(): ?string
144139
: 'EXPLAIN';
145140
$rows = $connection->getConnection()->query("$cmd $sql", $params);
146141
for ($explain = []; $row = $rows->fetch(); $explain[] = $row);
147-
} catch (\PDOException) {
142+
} catch (DriverException) {
148143
}
149144
}
150145

src/Database/Connection.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use JetBrains\PhpStorm\Language;
1313
use Nette;
1414
use Nette\Utils\Arrays;
15-
use PDOException;
1615

1716

1817
/**
@@ -82,7 +81,7 @@ public function connect(): void
8281

8382
try {
8483
$this->connection = $this->driver->connect();
85-
} catch (PDOException $e) {
84+
} catch (DriverException $e) {
8685
throw ConnectionException::from($e);
8786
}
8887

@@ -176,8 +175,8 @@ public function getInsertId(?string $sequence = null): string
176175
{
177176
try {
178177
return $this->getConnection()->getInsertId($sequence);
179-
} catch (PDOException $e) {
180-
throw $this->getDatabaseEngine()->convertException($e);
178+
} catch (DriverException $e) {
179+
throw $this->convertException($e);
181180
}
182181
}
183182

@@ -272,7 +271,7 @@ public function query(#[Language('SQL')] string $sql, #[Language('GenericSQL')]
272271
[$this->sql, $params] = $this->preprocess($sql, ...$params);
273272
try {
274273
$result = new Result($this, $this->sql, $params);
275-
} catch (PDOException $e) {
274+
} catch (DriverException $e) {
276275
Arrays::invoke($this->onQuery, $this, $e);
277276
throw $e;
278277
}
@@ -310,6 +309,13 @@ public function getLastQueryString(): ?string
310309
}
311310

312311

312+
public function convertException(DriverException $e): DriverException
313+
{
314+
$class = $this->getDatabaseEngine()->classifyException($e);
315+
return $class ? $class::from($e) : $e;
316+
}
317+
318+
313319
/********************* shortcuts ****************d*g**/
314320

315321

src/Database/DriverException.php

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,51 +13,46 @@
1313
/**
1414
* Base class for all errors in the driver or SQL server.
1515
*/
16-
class DriverException extends \PDOException
16+
class DriverException extends \Exception
1717
{
18-
public ?string $queryString = null;
19-
public ?array $params = null;
18+
public static function from(self $e): static
19+
{
20+
return new static($e->getMessage(), $e->sqlState, $e->getDriverCode() ?? 0, $e->query, $e);
21+
}
2022

2123

22-
public static function from(\PDOException $src): static
23-
{
24-
$e = new static($src->message, 0, $src);
25-
$e->file = $src->file;
26-
$e->line = $src->line;
27-
if (!$src->errorInfo && preg_match('#SQLSTATE\[(.*?)\] \[(.*?)\] (.*)#A', $src->message, $m)) {
28-
$m[2] = (int) $m[2];
29-
$e->errorInfo = array_slice($m, 1);
30-
$e->code = $m[1];
31-
} else {
32-
$e->errorInfo = $src->errorInfo;
33-
$e->code = $src->code;
34-
$e->code = $e->errorInfo[0] ?? $src->code;
35-
}
36-
37-
return $e;
24+
public function __construct(
25+
string $message,
26+
private readonly ?string $sqlState = null,
27+
private int $driverCode = 0,
28+
private readonly ?SqlLiteral $query = null,
29+
?\Throwable $previous = null,
30+
) {
31+
parent::__construct($message, 0, $previous);
32+
$this->code = $sqlState ?: null;
3833
}
3934

4035

4136
public function getDriverCode(): int|string|null
4237
{
43-
return $this->errorInfo[1] ?? null;
38+
return $this->driverCode ?: null;
4439
}
4540

4641

4742
public function getSqlState(): ?string
4843
{
49-
return $this->errorInfo[0] ?? null;
44+
return $this->sqlState;
5045
}
5146

5247

5348
public function getQueryString(): ?string
5449
{
55-
return $this->queryString;
50+
return $this->query?->getSql();
5651
}
5752

5853

5954
public function getParameters(): ?array
6055
{
61-
return $this->params;
56+
return $this->query?->getParameters();
6257
}
6358
}

src/Database/Drivers/Engine.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace Nette\Database\Drivers;
1111

12-
use Nette\Database;
12+
use Nette\Database\DriverException;
1313
use Nette\Database\TypeConverter;
1414

1515

@@ -31,10 +31,8 @@ interface Engine
3131
*/
3232
function isSupported(string $feature): bool;
3333

34-
/**
35-
* Converts PDOException to DriverException or its descendant.
36-
*/
37-
function convertException(\PDOException $e): Database\DriverException;
34+
/** Maps a driver exception to an appropriate exception class. */
35+
function classifyException(DriverException $e): ?string;
3836

3937
/** Converts a value from the database to a PHP value. */
4038
function convertToPhp(mixed $value, array $meta, TypeConverter $converter): mixed;

src/Database/Drivers/Engines/MSSQLEngine.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ public function isSupported(string $feature): bool
3232
}
3333

3434

35-
public function convertException(\PDOException $e): Nette\Database\DriverException
35+
public function classifyException(Nette\Database\DriverException $e): ?string
3636
{
37-
return Nette\Database\DriverException::from($e);
37+
return null;
3838
}
3939

4040

src/Database/Drivers/Engines/MySQLEngine.php

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,16 @@ public function isSupported(string $feature): bool
3636
}
3737

3838

39-
public function convertException(\PDOException $e): Nette\Database\DriverException
39+
public function classifyException(Nette\Database\DriverException $e): ?string
4040
{
41-
$code = $e->errorInfo[1] ?? null;
42-
if (in_array($code, [1216, 1217, 1451, 1452, 1701], strict: true)) {
43-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
44-
45-
} elseif (in_array($code, [1062, 1557, 1569, 1586], strict: true)) {
46-
return Nette\Database\UniqueConstraintViolationException::from($e);
47-
48-
} elseif ($code >= 2001 && $code <= 2028) {
49-
return Nette\Database\ConnectionException::from($e);
50-
51-
} elseif (in_array($code, [1048, 1121, 1138, 1171, 1252, 1263, 1566], strict: true)) {
52-
return Nette\Database\NotNullConstraintViolationException::from($e);
53-
54-
} else {
55-
return Nette\Database\DriverException::from($e);
56-
}
41+
$code = $e->getDriverCode();
42+
return match (true) {
43+
in_array($code, [1216, 1217, 1451, 1452, 1701], strict: true) => Nette\Database\ForeignKeyConstraintViolationException::class,
44+
in_array($code, [1062, 1557, 1569, 1586], strict: true) => Nette\Database\UniqueConstraintViolationException::class,
45+
$code >= 2001 && $code <= 2028 => Nette\Database\ConnectionException::class,
46+
in_array($code, [1048, 1121, 1138, 1171, 1252, 1263, 1566], strict: true) => Nette\Database\NotNullConstraintViolationException::class,
47+
default => null,
48+
};
5749
}
5850

5951

src/Database/Drivers/Engines/ODBCEngine.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ public function isSupported(string $feature): bool
2525
}
2626

2727

28-
public function convertException(\PDOException $e): Nette\Database\DriverException
28+
public function classifyException(Nette\Database\DriverException $e): ?string
2929
{
30-
return Nette\Database\DriverException::from($e);
30+
return null;
3131
}
3232

3333

src/Database/Drivers/Engines/OracleEngine.php

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,15 @@ public function isSupported(string $feature): bool
3535
}
3636

3737

38-
public function convertException(\PDOException $e): Nette\Database\DriverException
38+
public function classifyException(Nette\Database\DriverException $e): ?string
3939
{
40-
$code = $e->errorInfo[1] ?? null;
41-
if (in_array($code, [1, 2299, 38911], strict: true)) {
42-
return Nette\Database\UniqueConstraintViolationException::from($e);
43-
44-
} elseif (in_array($code, [1400], strict: true)) {
45-
return Nette\Database\NotNullConstraintViolationException::from($e);
46-
47-
} elseif (in_array($code, [2266, 2291, 2292], strict: true)) {
48-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
49-
50-
} else {
51-
return Nette\Database\DriverException::from($e);
52-
}
40+
$code = $e->getDriverCode();
41+
return match (true) {
42+
in_array($code, [1, 2299, 38911], strict: true) => Nette\Database\UniqueConstraintViolationException::class,
43+
in_array($code, [1400], strict: true) => Nette\Database\NotNullConstraintViolationException::class,
44+
in_array($code, [2266, 2291, 2292], strict: true) => Nette\Database\ForeignKeyConstraintViolationException::class,
45+
default => null,
46+
};
5347
}
5448

5549

src/Database/Drivers/Engines/PostgreSQLEngine.php

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,16 @@ public function isSupported(string $feature): bool
3232
}
3333

3434

35-
public function convertException(\PDOException $e): Nette\Database\DriverException
35+
public function classifyException(Nette\Database\DriverException $e): ?string
3636
{
37-
$code = $e->errorInfo[0] ?? null;
38-
if ($code === '0A000' && str_contains($e->getMessage(), 'truncate')) {
39-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
40-
41-
} elseif ($code === '23502') {
42-
return Nette\Database\NotNullConstraintViolationException::from($e);
43-
44-
} elseif ($code === '23503') {
45-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
46-
47-
} elseif ($code === '23505') {
48-
return Nette\Database\UniqueConstraintViolationException::from($e);
49-
50-
} elseif ($code === '08006') {
51-
return Nette\Database\ConnectionException::from($e);
52-
53-
} else {
54-
return Nette\Database\DriverException::from($e);
55-
}
37+
return match ($e->getSqlState()) {
38+
'0A000' => str_contains($e->getMessage(), 'truncate') ? Nette\Database\ForeignKeyConstraintViolationException::class : null,
39+
'23502' => Nette\Database\NotNullConstraintViolationException::class,
40+
'23503' => Nette\Database\ForeignKeyConstraintViolationException::class,
41+
'23505' => Nette\Database\UniqueConstraintViolationException::class,
42+
'08006' => Nette\Database\ConnectionException::class,
43+
default => null,
44+
};
5645
}
5746

5847

src/Database/Drivers/Engines/SQLServerEngine.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ public function isSupported(string $feature): bool
3232
}
3333

3434

35-
public function convertException(\PDOException $e): Nette\Database\DriverException
35+
public function classifyException(Nette\Database\DriverException $e): ?string
3636
{
37-
return Nette\Database\DriverException::from($e);
37+
return null;
3838
}
3939

4040

0 commit comments

Comments
 (0)