Issue #1831184 by sun, chx: Fixed DatabaseExceptionWrapper completely hides *unexpected* errors.
parent
c96966f079
commit
8b1a049654
|
@ -478,9 +478,9 @@ abstract class Connection extends PDO {
|
|||
* @param $query
|
||||
* The query to execute. In most cases this will be a string containing
|
||||
* an SQL query with placeholders. An already-prepared instance of
|
||||
* DatabaseStatementInterface may also be passed in order to allow calling
|
||||
* StatementInterface may also be passed in order to allow calling
|
||||
* code to manually bind variables to a query. If a
|
||||
* DatabaseStatementInterface is passed, the $args array will be ignored.
|
||||
* StatementInterface is passed, the $args array will be ignored.
|
||||
* It is extremely rare that module code will need to pass a statement
|
||||
* object to this method. It is used primarily for database drivers for
|
||||
* databases that require special LOB field handling.
|
||||
|
@ -492,7 +492,7 @@ abstract class Connection extends PDO {
|
|||
* An associative array of options to control how the query is run. See
|
||||
* the documentation for DatabaseConnection::defaultOptions() for details.
|
||||
*
|
||||
* @return Drupal\Core\Database\StatementInterface
|
||||
* @return \Drupal\Core\Database\StatementInterface
|
||||
* This method will return one of: the executed statement, the number of
|
||||
* rows affected by the query (not the number matched), or the generated
|
||||
* insert ID of the last query, depending on the value of
|
||||
|
@ -502,7 +502,7 @@ abstract class Connection extends PDO {
|
|||
* $options['throw_exception'] is TRUE.
|
||||
*
|
||||
* @throws PDOException
|
||||
* @throws Drupal\Core\Database\IntegrityConstraintViolationException
|
||||
* @throws \Drupal\Core\Database\IntegrityConstraintViolationException
|
||||
*/
|
||||
public function query($query, array $args = array(), $options = array()) {
|
||||
|
||||
|
@ -513,7 +513,7 @@ abstract class Connection extends PDO {
|
|||
// We allow either a pre-bound statement object or a literal string.
|
||||
// In either case, we want to end up with an executed statement object,
|
||||
// which we pass to PDOStatement::execute.
|
||||
if ($query instanceof DatabaseStatementInterface) {
|
||||
if ($query instanceof StatementInterface) {
|
||||
$stmt = $query;
|
||||
$stmt->execute(NULL, $options);
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ abstract class Connection extends PDO {
|
|||
// Wrap the exception in another exception, because PHP does not allow
|
||||
// overriding Exception::getMessage(). Its message is the extra database
|
||||
// debug information.
|
||||
$query_string = ($query instanceof DatabaseStatementInterface) ? $stmt->getQueryString() : $query;
|
||||
$query_string = ($query instanceof StatementInterface) ? $stmt->getQueryString() : $query;
|
||||
$message = $e->getMessage() . ": " . $query_string . "; " . print_r($args, TRUE);
|
||||
// Match all SQLSTATE 23xxx errors.
|
||||
if (substr($e->getCode(), -6, -3) == '23') {
|
||||
|
|
|
@ -11,7 +11,7 @@ use PDO;
|
|||
use PDOStatement;
|
||||
|
||||
/**
|
||||
* Default implementation of DatabaseStatementInterface.
|
||||
* Default implementation of StatementInterface.
|
||||
*
|
||||
* PDO allows us to extend the PDOStatement class to provide additional
|
||||
* functionality beyond that offered by default. We do need extra
|
||||
|
@ -32,7 +32,7 @@ class Statement extends PDOStatement implements StatementInterface {
|
|||
*/
|
||||
public $dbh;
|
||||
|
||||
protected function __construct($dbh) {
|
||||
protected function __construct(Connection $dbh) {
|
||||
$this->dbh = $dbh;
|
||||
$this->setFetchMode(PDO::FETCH_OBJ);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,25 @@ use Traversable;
|
|||
*/
|
||||
interface StatementInterface extends Traversable {
|
||||
|
||||
/**
|
||||
* Constructs a new PDOStatement object.
|
||||
*
|
||||
* The PDO manual does not document this constructor, but when overriding the
|
||||
* PDOStatement class with a custom without this constructor, PDO will throw
|
||||
* the internal exception/warning:
|
||||
*
|
||||
* "PDO::query(): SQLSTATE[HY000]: General error: user-supplied statement does
|
||||
* not accept constructor arguments"
|
||||
*
|
||||
* PDO enforces that the access type of this constructor must be protected,
|
||||
* and lastly, it also enforces that a custom PDOStatement interface (like
|
||||
* this) omits the constructor (declaring it results in fatal errors
|
||||
* complaining about "the access type must not be public" if it is public, and
|
||||
* "the access type must be omitted" if it is protected; i.e., conflicting
|
||||
* statements). The access type has to be protected.
|
||||
*/
|
||||
//protected function __construct(Connection $dbh);
|
||||
|
||||
/**
|
||||
* Executes a prepared statement
|
||||
*
|
||||
|
@ -113,7 +132,7 @@ interface StatementInterface extends Traversable {
|
|||
/**
|
||||
* Fetches the next row and returns it as an object.
|
||||
*
|
||||
* The object will be of the class specified by DatabaseStatementInterface::setFetchMode()
|
||||
* The object will be of the class specified by StatementInterface::setFetchMode()
|
||||
* or stdClass if not specified.
|
||||
*/
|
||||
// public function fetchObject();
|
||||
|
|
|
@ -13,7 +13,7 @@ use PDO;
|
|||
use PDOException;
|
||||
|
||||
/**
|
||||
* An implementation of DatabaseStatementInterface that prefetches all data.
|
||||
* An implementation of StatementInterface that prefetches all data.
|
||||
*
|
||||
* This class behaves very similar to a PDOStatement but as it always fetches
|
||||
* every row it is possible to manipulate those results.
|
||||
|
@ -342,7 +342,7 @@ class StatementPrefetch implements Iterator, StatementInterface {
|
|||
return isset($this->currentRow);
|
||||
}
|
||||
|
||||
/* Implementations of DatabaseStatementInterface. */
|
||||
/* Implementations of StatementInterface. */
|
||||
|
||||
public function rowCount() {
|
||||
return $this->rowCount;
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains Drupal\system\Tests\Database\DatabaseExceptionWrapperTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\system\Tests\Database;
|
||||
|
||||
use Drupal\Core\Database\DatabaseExceptionWrapper;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\simpletest\UnitTestBase;
|
||||
|
||||
/**
|
||||
* Tests DatabaseExceptionWrapper thrown.
|
||||
*/
|
||||
class DatabaseExceptionWrapperTest extends UnitTestBase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Database exceptiontests',
|
||||
'description' => 'Tests exceptions thrown by queries.',
|
||||
'group' => 'Database',
|
||||
);
|
||||
}
|
||||
|
||||
function testDatabaseExceptionWrapper() {
|
||||
$connection = Database::getConnection();
|
||||
$query = $connection->prepare('bananas');
|
||||
try {
|
||||
$connection->query($query);
|
||||
$this->fail('The expected exception is not thrown.');
|
||||
}
|
||||
catch (DatabaseExceptionWrapper $e) {
|
||||
$this->pass('The expected exception has been thrown.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue