Skip to content

Commit

Permalink
Merge pull request doctrine#3536 from jwage/improve-exception-messages
Browse files Browse the repository at this point in the history
Improve consistency of exception message formatting.
  • Loading branch information
morozov committed Aug 27, 2019
2 parents 9e5af55 + fb13d7d commit c36f826
Show file tree
Hide file tree
Showing 88 changed files with 613 additions and 248 deletions.
9 changes: 6 additions & 3 deletions lib/Doctrine/DBAL/Cache/ArrayStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use function array_values;
use function count;
use function reset;
use function sprintf;

class ArrayStatement implements IteratorAggregate, ResultStatement
{
Expand Down Expand Up @@ -48,7 +49,7 @@ public function __construct(array $data)
*/
public function closeCursor() : void
{
unset($this->data);
$this->data = null;
}

/**
Expand Down Expand Up @@ -77,7 +78,7 @@ public function rowCount() : int
public function setFetchMode($fetchMode, ...$args) : void
{
if (count($args) > 0) {
throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode()');
throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode().');
}

$this->defaultFetchMode = $fetchMode;
Expand Down Expand Up @@ -121,7 +122,9 @@ public function fetch($fetchMode = null, ...$args)
return reset($row);
}

throw new InvalidArgumentException('Invalid fetch-style given for fetching result.');
throw new InvalidArgumentException(
sprintf('Invalid fetch mode given for fetching result, %d given.', $fetchMode)
);
}

/**
Expand Down
27 changes: 16 additions & 11 deletions lib/Doctrine/DBAL/DBALException.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,28 @@ class DBALException extends Exception
*/
public static function driverExceptionDuringQuery(Driver $driver, Throwable $driverEx, $sql, array $params = [])
{
$msg = "An exception occurred while executing '" . $sql . "'";
if ($params) {
$msg .= ' with params ' . self::formatParameters($params);
}
$msg .= ":\n\n" . $driverEx->getMessage();
$messageFormat = <<<'MESSAGE'
An exception occurred while executing "%s"%s:
%s
MESSAGE;

$message = sprintf(
$messageFormat,
$sql,
$params !== [] ? sprintf(' with params %s', self::formatParameters($params)) : '',
$driverEx->getMessage()
);

return static::wrapException($driver, $driverEx, $msg);
return static::wrapException($driver, $driverEx, $message);
}

/**
* @return self
*/
public static function driverException(Driver $driver, Throwable $driverEx)
{
return static::wrapException($driver, $driverEx, 'An exception occurred in driver: ' . $driverEx->getMessage());
return static::wrapException($driver, $driverEx, sprintf('An exception occurred in driver with message: %s', $driverEx->getMessage()));
}

/**
Expand All @@ -64,11 +71,9 @@ private static function wrapException(Driver $driver, Throwable $driverEx, $msg)
* Returns a human-readable representation of an array of parameters.
* This properly handles binary data by returning a hex representation.
*
* @param mixed[] $params
*
* @return string
* @param array<mixed, mixed> $params
*/
private static function formatParameters(array $params)
private static function formatParameters(array $params) : string
{
return '[' . implode(', ', array_map(static function ($param) {
if (is_resource($param)) {
Expand Down
16 changes: 16 additions & 0 deletions lib/Doctrine/DBAL/Driver/Mysqli/Exception/ConnectionError.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Driver\Mysqli\Exception;

use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use mysqli;

final class ConnectionError extends MysqliException
{
public static function new(mysqli $connection) : self
{
return new self($connection->error, $connection->sqlstate ?: null, $connection->errno);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Driver\Mysqli\Exception;

use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use function sprintf;

final class FailedReadingStreamOffset extends MysqliException
{
public static function new(int $offset) : self
{
return new self(sprintf('Failed reading the stream resource for parameter offset %d.', $offset));
}
}
16 changes: 16 additions & 0 deletions lib/Doctrine/DBAL/Driver/Mysqli/Exception/StatementError.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Driver\Mysqli\Exception;

use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use mysqli_stmt;

final class StatementError extends MysqliException
{
public static function new(mysqli_stmt $statement) : self
{
return new self($statement->error, $statement->sqlstate ?: null, $statement->errno);
}
}
19 changes: 19 additions & 0 deletions lib/Doctrine/DBAL/Driver/Mysqli/Exception/UnknownFetchMode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Driver\Mysqli\Exception;

use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use function sprintf;

final class UnknownFetchMode extends MysqliException
{
/**
* @param mixed $fetchMode
*/
public static function new($fetchMode) : self
{
return new self(sprintf('Unknown fetch mode %d.', $fetchMode));
}
}
19 changes: 19 additions & 0 deletions lib/Doctrine/DBAL/Driver/Mysqli/Exception/UnknownType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Driver\Mysqli\Exception;

use Doctrine\DBAL\Driver\Mysqli\MysqliException;
use function sprintf;

final class UnknownType extends MysqliException
{
/**
* @param mixed $type
*/
public static function new($type) : self
{
return new self(sprintf('Unknown type, %d given.', $type));
}
}
11 changes: 6 additions & 5 deletions lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Doctrine\DBAL\Driver\Mysqli;

use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
use Doctrine\DBAL\Driver\PingableConnection;
use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
Expand Down Expand Up @@ -73,7 +74,7 @@ public function __construct(array $params, $username, $password, array $driverOp
});
try {
if (! $this->conn->real_connect($host, $username, $password, $dbname, $port, $socket, $flags)) {
throw MysqliException::fromConnectionError($this->conn);
throw ConnectionError::new($this->conn);
}
} finally {
restore_error_handler();
Expand Down Expand Up @@ -161,7 +162,7 @@ public function quote(string $input) : string
public function exec(string $statement) : int
{
if ($this->conn->query($statement) === false) {
throw MysqliException::fromConnectionError($this->conn);
throw ConnectionError::new($this->conn);
}

return $this->conn->affected_rows;
Expand Down Expand Up @@ -189,7 +190,7 @@ public function beginTransaction() : void
public function commit() : void
{
if (! $this->conn->commit()) {
throw MysqliException::fromConnectionError($this->conn);
throw ConnectionError::new($this->conn);
}
}

Expand All @@ -199,7 +200,7 @@ public function commit() : void
public function rollBack() : void
{
if (! $this->conn->rollback()) {
throw MysqliException::fromConnectionError($this->conn);
throw ConnectionError::new($this->conn);
}
}

Expand Down Expand Up @@ -242,7 +243,7 @@ private function setDriverOptions(array $driverOptions = [])
continue;
}

throw MysqliException::fromConnectionError($this->conn);
throw ConnectionError::new($this->conn);
}
}

Expand Down
11 changes: 0 additions & 11 deletions lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,10 @@
namespace Doctrine\DBAL\Driver\Mysqli;

use Doctrine\DBAL\Driver\AbstractDriverException;
use mysqli;
use mysqli_stmt;

/**
* Exception thrown in case the mysqli driver errors.
*/
class MysqliException extends AbstractDriverException
{
public static function fromConnectionError(mysqli $connection) : self
{
return new self($connection->error, $connection->sqlstate ?: null, $connection->errno);
}

public static function fromStatementError(mysqli_stmt $statement) : self
{
return new self($statement->error, $statement->sqlstate ?: null, $statement->errno);
}
}
28 changes: 16 additions & 12 deletions lib/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
namespace Doctrine\DBAL\Driver\Mysqli;

use Doctrine\DBAL\Driver\DriverException;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError;
use Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset;
use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownFetchMode;
use Doctrine\DBAL\Driver\Mysqli\Exception\UnknownType;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Exception\InvalidArgumentException;
Expand All @@ -25,7 +30,6 @@
use function is_array;
use function is_int;
use function is_resource;
use function sprintf;
use function str_repeat;

class MysqliStatement implements IteratorAggregate, Statement
Expand Down Expand Up @@ -87,7 +91,7 @@ public function __construct(mysqli $conn, $prepareString)
$stmt = $conn->prepare($prepareString);

if ($stmt === false) {
throw MysqliException::fromConnectionError($this->_conn);
throw ConnectionError::new($this->_conn);
}

$this->_stmt = $stmt;
Expand All @@ -109,7 +113,7 @@ public function bindParam($column, &$variable, $type = ParameterType::STRING, $l
assert(is_int($column));

if (! isset(self::$_paramTypeMap[$type])) {
throw new MysqliException(sprintf("Unknown type: '%s'", $type));
throw UnknownType::new($type);
}

$this->_bindedValues[$column] =& $variable;
Expand All @@ -124,7 +128,7 @@ public function bindValue($param, $value, $type = ParameterType::STRING) : void
assert(is_int($param));

if (! isset(self::$_paramTypeMap[$type])) {
throw new MysqliException(sprintf("Unknown type: '%s'", $type));
throw UnknownType::new($type);
}

$this->_values[$param] = $value;
Expand All @@ -139,14 +143,14 @@ public function execute($params = null) : void
{
if ($params !== null && count($params) > 0) {
if (! $this->bindUntypedValues($params)) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}
} else {
$this->bindTypedParameters();
}

if (! $this->_stmt->execute()) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}

if ($this->_columnNames === null) {
Expand Down Expand Up @@ -193,7 +197,7 @@ public function execute($params = null) : void
}

if (! $this->_stmt->bind_result(...$refs)) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}
}

Expand Down Expand Up @@ -232,7 +236,7 @@ private function bindTypedParameters()
}

if (count($values) > 0 && ! $this->_stmt->bind_param($types, ...$values)) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}

$this->sendLongData($streams);
Expand All @@ -250,11 +254,11 @@ private function sendLongData($streams)
$chunk = fread($stream, 8192);

if ($chunk === false) {
throw new MysqliException("Failed reading the stream resource for parameter offset ${paramNr}.");
throw FailedReadingStreamOffset::new($paramNr);
}

if (! $this->_stmt->send_long_data($paramNr - 1, $chunk)) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}
}
}
Expand Down Expand Up @@ -322,7 +326,7 @@ public function fetch($fetchMode = null, ...$args)
}

if ($values === false) {
throw MysqliException::fromStatementError($this->_stmt);
throw StatementError::new($this->_stmt);
}

if ($fetchMode === FetchMode::NUMERIC) {
Expand All @@ -344,7 +348,7 @@ public function fetch($fetchMode = null, ...$args)
return (object) $assoc;

default:
throw new MysqliException(sprintf("Unknown fetch type '%s'", $fetchMode));
throw UnknownFetchMode::new($fetchMode);
}
}

Expand Down
6 changes: 3 additions & 3 deletions lib/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public static function convertPositionalToNamedPlaceholders($statement)

if ($currentLiteralDelimiter) {
throw new OCI8Exception(sprintf(
'The statement contains non-terminated string literal starting at offset %d',
'The statement contains non-terminated string literal starting at offset %d.',
$tokenOffset - 1
));
}
Expand Down Expand Up @@ -411,7 +411,7 @@ public function fetch($fetchMode = null, ...$args)
}

if (! isset(self::$fetchModeMap[$fetchMode])) {
throw new InvalidArgumentException('Invalid fetch style: ' . $fetchMode);
throw new InvalidArgumentException(sprintf('Invalid fetch mode %d.', $fetchMode));
}

return oci_fetch_array(
Expand All @@ -438,7 +438,7 @@ public function fetchAll($fetchMode = null, ...$args)
}

if (! isset(self::$fetchModeMap[$fetchMode])) {
throw new InvalidArgumentException('Invalid fetch style: ' . $fetchMode);
throw new InvalidArgumentException(sprintf('Invalid fetch mode %d.', $fetchMode));
}

if (self::$fetchModeMap[$fetchMode] === OCI_BOTH) {
Expand Down
Loading

0 comments on commit c36f826

Please sign in to comment.