Skip to content

Commit 89cf65b

Browse files
committed
exceptions are converted in PDODriver
1 parent 50aa657 commit 89cf65b

14 files changed

Lines changed: 72 additions & 76 deletions

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: 19 additions & 17 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;
19-
2019
public ?array $params = null;
20+
private int|string|null $driverCode = null;
21+
private string|null $sqlState = null;
2122

2223

23-
public static function from(\PDOException $src): static
24+
public function __construct(string $message = '', $code = 0, \Throwable $previous = null)
2425
{
25-
$e = new static($src->message, 0, $src);
26-
$e->file = $src->file;
27-
$e->line = $src->line;
28-
if (!$src->errorInfo && preg_match('#SQLSTATE\[(.*?)\] \[(.*?)\] (.*)#A', $src->message, $m)) {
29-
$m[2] = (int) $m[2];
30-
$e->errorInfo = array_slice($m, 1);
31-
$e->code = $m[1];
32-
} else {
33-
$e->errorInfo = $src->errorInfo;
34-
$e->code = $src->code;
35-
$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;
3631
}
37-
return $e;
32+
}
33+
34+
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
@@ -42,23 +42,23 @@ public function connect(string $dsn, string $user = null, string $password = nul
4242
}
4343

4444

45-
public function convertException(\PDOException $e): Nette\Database\DriverException
45+
public function detectExceptionClass(\PDOException $e): ?string
4646
{
4747
$code = $e->errorInfo[1] ?? null;
4848
if (in_array($code, [1216, 1217, 1451, 1452, 1701], true)) {
49-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
49+
return Nette\Database\ForeignKeyConstraintViolationException::class;
5050

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

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

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

6060
} else {
61-
return Nette\Database\DriverException::from($e);
61+
return null;
6262
}
6363
}
6464

src/Database/Drivers/OciDriver.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,20 @@ public function connect(string $dsn, string $user = null, string $password = nul
2828
}
2929

3030

31-
public function convertException(\PDOException $e): Nette\Database\DriverException
31+
public function detectExceptionClass(\PDOException $e): ?string
3232
{
3333
$code = $e->errorInfo[1] ?? null;
3434
if (in_array($code, [1, 2299, 38911], true)) {
35-
return Nette\Database\UniqueConstraintViolationException::from($e);
35+
return Nette\Database\UniqueConstraintViolationException::class;
3636

3737
} elseif (in_array($code, [1400], true)) {
38-
return Nette\Database\NotNullConstraintViolationException::from($e);
38+
return Nette\Database\NotNullConstraintViolationException::class;
3939

4040
} elseif (in_array($code, [2266, 2291, 2292], true)) {
41-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
41+
return Nette\Database\ForeignKeyConstraintViolationException::class;
4242

4343
} else {
44-
return Nette\Database\DriverException::from($e);
44+
return null;
4545
}
4646
}
4747

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: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function connect(string $dsn, string $user = null, string $password = nul
4040
$this->pdo = new PDO($dsn, $user, $password, $options);
4141
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
4242
} catch (PDOException $e) {
43-
throw Nette\Database\ConnectionException::from($e);
43+
throw $this->convertException($e, Nette\Database\ConnectionException::class);
4444
}
4545
}
4646

@@ -121,7 +121,30 @@ public function quote(string $string, int $type = PDO::PARAM_STR): string
121121
try {
122122
return $this->pdo->quote($string, $type);
123123
} catch (PDOException $e) {
124-
throw DriverException::from($e);
124+
throw $this->convertException($e);
125+
}
126+
}
127+
128+
129+
public function convertException(\PDOException $src, string $class = null): DriverException
130+
{
131+
if ($src->errorInfo) {
132+
[$sqlState, $driverCode] = $src->errorInfo;
133+
} elseif (preg_match('#SQLSTATE\[(.*?)\] \[(.*?)\] (.*)#A', $src->getMessage(), $m)) {
134+
[, $sqlState, $driverCode] = $m;
125135
}
136+
137+
$class = $this->detectExceptionClass($src) ?? $class ?? DriverException::class;
138+
$e = new $class($src->getMessage(), $sqlState ?? $src->getCode(), $src);
139+
if (isset($sqlState)) {
140+
$e->setDriverCode($sqlState, (int) $driverCode);
141+
}
142+
return $e;
143+
}
144+
145+
146+
public function detectExceptionClass(\PDOException $e): ?string
147+
{
148+
return null;
126149
}
127150
}

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
@@ -28,34 +28,34 @@ public function connect(string $dsn, string $user = null, string $password = nul
2828
}
2929

3030

31-
public function convertException(\PDOException $e): Nette\Database\DriverException
31+
public function detectExceptionClass(\PDOException $e): ?string
3232
{
3333
$code = $e->errorInfo[1] ?? null;
3434
$msg = $e->getMessage();
3535
if ($code !== 19) {
36-
return Nette\Database\DriverException::from($e);
36+
return null;
3737

3838
} elseif (
3939
str_contains($msg, 'must be unique')
4040
|| str_contains($msg, 'is not unique')
4141
|| str_contains($msg, 'UNIQUE constraint failed')
4242
) {
43-
return Nette\Database\UniqueConstraintViolationException::from($e);
43+
return Nette\Database\UniqueConstraintViolationException::class;
4444

4545
} elseif (
4646
str_contains($msg, 'may not be null')
4747
|| str_contains($msg, 'NOT NULL constraint failed')
4848
) {
49-
return Nette\Database\NotNullConstraintViolationException::from($e);
49+
return Nette\Database\NotNullConstraintViolationException::class;
5050

5151
} elseif (
5252
str_contains($msg, 'foreign key constraint failed')
5353
|| str_contains($msg, 'FOREIGN KEY constraint failed')
5454
) {
55-
return Nette\Database\ForeignKeyConstraintViolationException::from($e);
55+
return Nette\Database\ForeignKeyConstraintViolationException::class;
5656

5757
} else {
58-
return Nette\Database\ConstraintViolationException::from($e);
58+
return Nette\Database\ConstraintViolationException::class;
5959
}
6060
}
6161

src/Database/Drivers/SqlsrvDriver.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ public function connect(string $dsn, string $user = null, string $password = nul
2727
}
2828

2929

30-
public function convertException(\PDOException $e): Nette\Database\DriverException
31-
{
32-
return Nette\Database\DriverException::from($e);
33-
}
34-
35-
3630
/********************* SQL ****************d*g**/
3731

3832

0 commit comments

Comments
 (0)