Skip to content

Commit 2cf6efa

Browse files
committed
exceptions are converted in PdoDriver
1 parent c7c81ee commit 2cf6efa

File tree

13 files changed

+71
-74
lines changed

13 files changed

+71
-74
lines changed

src/Database/Driver.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ interface Driver
2929
*/
3030
function connect(string $dsn, ?string $user = null, ?string $password = null, ?array $options = null): void;
3131

32-
/**
33-
* Converts PDOException to DriverException or its descendant.
34-
*/
35-
function convertException(\PDOException $e): DriverException;
36-
3732
function query(string $queryString, array $params): ResultDriver;
3833

3934
function beginTransaction(): void;

src/Database/DriverException.php

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,42 @@
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
{
1818
public ?string $queryString = null;
1919
public ?array $params = null;
20+
private int|string|null $driverCode = null;
21+
private string|null $sqlState = null;
2022

2123

22-
public static function from(\PDOException $src): static
24+
public function __construct(string $message = '', $code = 0, ?\Throwable $previous = null)
2325
{
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;
26+
parent::__construct($message, 0, $previous);
27+
$this->code = $code;
28+
if ($previous) {
29+
$this->file = $previous->file;
30+
$this->line = $previous->line;
3531
}
32+
}
33+
3634

37-
return $e;
35+
/** @internal */
36+
public function setDriverCode(string $state, int|string $code): void
37+
{
38+
$this->sqlState = $state;
39+
$this->driverCode = $code;
3840
}
3941

4042

4143
public function getDriverCode(): int|string|null
4244
{
43-
return $this->errorInfo[1] ?? null;
45+
return $this->driverCode;
4446
}
4547

4648

4749
public function getSqlState(): ?string
4850
{
49-
return $this->errorInfo[0] ?? null;
51+
return $this->sqlState;
5052
}
5153

5254

src/Database/Drivers/MsSqlDriver.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,6 @@
1717
*/
1818
class MsSqlDriver extends PdoDriver
1919
{
20-
public function convertException(\PDOException $e): Nette\Database\DriverException
21-
{
22-
return Nette\Database\DriverException::from($e);
23-
}
24-
25-
26-
/********************* SQL ****************d*g**/
27-
28-
2920
public function delimite(string $name): string
3021
{
3122
// @see https://msdn.microsoft.com/en-us/library/ms176027.aspx

src/Database/Drivers/MySqlDriver.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,23 @@ public function connect(
6464
}
6565

6666

67-
public function convertException(\PDOException $e): Nette\Database\DriverException
67+
public function detectExceptionClass(\PDOException $e): ?string
6868
{
6969
$code = $e->errorInfo[1] ?? null;
7070
if (in_array($code, [1216, 1217, 1451, 1452, 1701], strict: true)) {
71-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
71+
return Nette\Database\ForeignKeyConstraintViolationException::class;
7272

7373
} elseif (in_array($code, [1062, 1557, 1569, 1586], strict: true)) {
74-
return Nette\Database\UniqueConstraintViolationException::from($e);
74+
return Nette\Database\UniqueConstraintViolationException::class;
7575

7676
} elseif ($code >= 2001 && $code <= 2028) {
77-
return Nette\Database\ConnectionException::from($e);
77+
return Nette\Database\ConnectionException::class;
7878

7979
} elseif (in_array($code, [1048, 1121, 1138, 1171, 1252, 1263, 1566], strict: true)) {
80-
return Nette\Database\NotNullConstraintViolationException::from($e);
80+
return Nette\Database\NotNullConstraintViolationException::class;
8181

8282
} else {
83-
return Nette\Database\DriverException::from($e);
83+
return null;
8484
}
8585
}
8686

src/Database/Drivers/OciDriver.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,20 @@ public function connect(
3333
}
3434

3535

36-
public function convertException(\PDOException $e): Nette\Database\DriverException
36+
public function detectExceptionClass(\PDOException $e): ?string
3737
{
3838
$code = $e->errorInfo[1] ?? null;
3939
if (in_array($code, [1, 2299, 38911], strict: true)) {
40-
return Nette\Database\UniqueConstraintViolationException::from($e);
40+
return Nette\Database\UniqueConstraintViolationException::class;
4141

4242
} elseif (in_array($code, [1400], strict: true)) {
43-
return Nette\Database\NotNullConstraintViolationException::from($e);
43+
return Nette\Database\NotNullConstraintViolationException::class;
4444

4545
} elseif (in_array($code, [2266, 2291, 2292], strict: true)) {
46-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
46+
return Nette\Database\ForeignKeyConstraintViolationException::class;
4747

4848
} else {
49-
return Nette\Database\DriverException::from($e);
49+
return null;
5050
}
5151
}
5252

src/Database/Drivers/OdbcDriver.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,6 @@
1717
*/
1818
class OdbcDriver extends PdoDriver
1919
{
20-
public function convertException(\PDOException $e): Nette\Database\DriverException
21-
{
22-
return Nette\Database\DriverException::from($e);
23-
}
24-
25-
26-
/********************* SQL ****************d*g**/
27-
28-
2920
public function delimite(string $name): string
3021
{
3122
return '[' . str_replace(['[', ']'], ['[[', ']]'], $name) . ']';

src/Database/Drivers/PdoDriver.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function connect(
3535
$this->pdo = new PDO($dsn, $user, $password, $options);
3636
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
3737
} catch (PDOException $e) {
38-
throw Nette\Database\ConnectionException::from($e);
38+
throw $this->convertException($e, Nette\Database\ConnectionException::class);
3939
}
4040
}
4141

@@ -116,7 +116,31 @@ public function quote(string $string, int $type = PDO::PARAM_STR): string
116116
try {
117117
return $this->pdo->quote($string, $type);
118118
} catch (PDOException $e) {
119-
throw DriverException::from($e);
119+
throw $this->convertException($e);
120120
}
121121
}
122+
123+
124+
public function convertException(\PDOException $src, ?string $class = null): DriverException
125+
{
126+
if ($src->errorInfo) {
127+
[$sqlState, $driverCode] = $src->errorInfo;
128+
} elseif (preg_match('#SQLSTATE\[(.*?)\] \[(.*?)\] (.*)#A', $src->getMessage(), $m)) {
129+
[, $sqlState, $driverCode] = $m;
130+
}
131+
132+
$class = $this->detectExceptionClass($src) ?? $class ?? DriverException::class;
133+
$e = new $class($src->getMessage(), $sqlState ?? $src->getCode(), $src);
134+
if (isset($sqlState)) {
135+
$e->setDriverCode($sqlState, (int) $driverCode);
136+
}
137+
138+
return $e;
139+
}
140+
141+
142+
public function detectExceptionClass(\PDOException $e): ?string
143+
{
144+
return null;
145+
}
122146
}

src/Database/Drivers/PgSqlDriver.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,26 @@
1717
*/
1818
class PgSqlDriver extends PdoDriver
1919
{
20-
public function convertException(\PDOException $e): Nette\Database\DriverException
20+
public function detectExceptionClass(\PDOException $e): ?string
2121
{
2222
$code = $e->errorInfo[0] ?? null;
2323
if ($code === '0A000' && str_contains($e->getMessage(), 'truncate')) {
24-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
24+
return Nette\Database\ForeignKeyConstraintViolationException::class;
2525

2626
} elseif ($code === '23502') {
27-
return Nette\Database\NotNullConstraintViolationException::from($e);
27+
return Nette\Database\NotNullConstraintViolationException::class;
2828

2929
} elseif ($code === '23503') {
30-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
30+
return Nette\Database\ForeignKeyConstraintViolationException::class;
3131

3232
} elseif ($code === '23505') {
33-
return Nette\Database\UniqueConstraintViolationException::from($e);
33+
return Nette\Database\UniqueConstraintViolationException::class;
3434

3535
} elseif ($code === '08006') {
36-
return Nette\Database\ConnectionException::from($e);
36+
return Nette\Database\ConnectionException::class;
3737

3838
} else {
39-
return Nette\Database\DriverException::from($e);
39+
return null;
4040
}
4141
}
4242

src/Database/Drivers/SqliteDriver.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,34 +33,34 @@ public function connect(
3333
}
3434

3535

36-
public function convertException(\PDOException $e): Nette\Database\DriverException
36+
public function detectExceptionClass(\PDOException $e): ?string
3737
{
3838
$code = $e->errorInfo[1] ?? null;
3939
$msg = $e->getMessage();
4040
if ($code !== 19) {
41-
return Nette\Database\DriverException::from($e);
41+
return null;
4242

4343
} elseif (
4444
str_contains($msg, 'must be unique')
4545
|| str_contains($msg, 'is not unique')
4646
|| str_contains($msg, 'UNIQUE constraint failed')
4747
) {
48-
return Nette\Database\UniqueConstraintViolationException::from($e);
48+
return Nette\Database\UniqueConstraintViolationException::class;
4949

5050
} elseif (
5151
str_contains($msg, 'may not be null')
5252
|| str_contains($msg, 'NOT NULL constraint failed')
5353
) {
54-
return Nette\Database\NotNullConstraintViolationException::from($e);
54+
return Nette\Database\NotNullConstraintViolationException::class;
5555

5656
} elseif (
5757
str_contains($msg, 'foreign key constraint failed')
5858
|| str_contains($msg, 'FOREIGN KEY constraint failed')
5959
) {
60-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
60+
return Nette\Database\ForeignKeyConstraintViolationException::class;
6161

6262
} else {
63-
return Nette\Database\ConstraintViolationException::from($e);
63+
return Nette\Database\ConstraintViolationException::class;
6464
}
6565
}
6666

src/Database/Drivers/SqlsrvDriver.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,6 @@ public function connect(
3333
}
3434

3535

36-
public function convertException(\PDOException $e): Nette\Database\DriverException
37-
{
38-
return Nette\Database\DriverException::from($e);
39-
}
40-
41-
4236
/********************* SQL ****************d*g**/
4337

4438

0 commit comments

Comments
 (0)