Skip to content

Commit

Permalink
Expose underlying errors on Oracle
Browse files Browse the repository at this point in the history
  • Loading branch information
simPod committed Oct 4, 2021
1 parent d4a6d77 commit 2055cee
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 2 deletions.
18 changes: 17 additions & 1 deletion src/Driver/OCI8/Exception/Error.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
use Doctrine\DBAL\Driver\AbstractException;

use function assert;
use function explode;
use function oci_error;
use function str_replace;

/**
* @internal
Expand All @@ -16,6 +18,8 @@
*/
final class Error extends AbstractException
{
private const CODE_TRANSACTION_ROLLED_BACK = 2091;

/**
* @param resource $resource
*/
Expand All @@ -24,6 +28,18 @@ public static function new($resource): self
$error = oci_error($resource);
assert($error !== false);

return new self($error['message'], null, $error['code']);
$code = $error['code'];
$message = $error['message'];
if ($code === self::CODE_TRANSACTION_ROLLED_BACK) {
// There's no way this can be unit-tested as it's impossible to mock $resource
//ORA-02091: transaction rolled back
//ORA-00001: unique constraint (DOCTRINE.GH3423_UNIQUE) violated
[$firstMessage, $secondMessage] = explode("\n", $message, 2);

[$code, $message] = explode(': ', $secondMessage, 2);
$code = (int) str_replace('ORA-', '', $code);
}

return new self($message, null, $code);
}
}
18 changes: 17 additions & 1 deletion src/Driver/PDO/Exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,38 @@
use Doctrine\DBAL\Driver\AbstractException;
use PDOException;

use function explode;
use function str_replace;

/**
* @internal
*
* @psalm-immutable
*/
final class Exception extends AbstractException
{
private const CODE_TRANSACTION_ROLLED_BACK = 2091;

public static function new(PDOException $exception): self
{
$message = $exception->getMessage();

if ($exception->errorInfo !== null) {
[$sqlState, $code] = $exception->errorInfo;
} else {
$code = $exception->getCode();
$sqlState = null;
}

return new self($exception->getMessage(), $sqlState, $code, $exception);
if ($code === self::CODE_TRANSACTION_ROLLED_BACK) {
//ORA-02091: transaction rolled back
//ORA-00001: unique constraint (DOCTRINE.GH3423_UNIQUE) violated
[$firstMessage, $secondMessage] = explode("\n", $message, 2);

[$code, $message] = explode(': ', $secondMessage, 2);
$code = (int) str_replace('ORA-', '', $code);
}

return new self($message, $sqlState, $code, $exception);
}
}
21 changes: 21 additions & 0 deletions tests/Driver/PDO/ExceptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,25 @@ public function testOriginalExceptionIsInChain(): void
{
self::assertSame($this->wrappedException, $this->exception->getPrevious());
}

public function testExposesUnderlyingErrorOnOracle(): void
{
$pdoException = new PDOException(<<<TEXT
OCITransCommit: ORA-02091: transaction rolled back
ORA-00001: unique constraint (DOCTRINE.C1_UNIQUE) violated
(/private/tmp/php-20211003-35441-1sggrmq/php-8.0.11/ext/pdo_oci/oci_driver.c:410)
TEXT);

$pdoException->errorInfo = [self::SQLSTATE, 2091,

];

$exception = Exception::new($pdoException);

self::assertSame(1, $exception->getCode());
self::assertStringContainsString(
'unique constraint (DOCTRINE.C1_UNIQUE) violated',
$exception->getMessage()
);
}
}

0 comments on commit 2055cee

Please sign in to comment.