There's a PDO exception that simpletests creates as follows:

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'drupal_7_dev.simpletest107742access' doesn't exist: SELECT mask FROM {access} WHERE status = :status AND type = :type; Array ( [:status] => 0 [:type] => host )

The current error handling in Drupal silently ignores this error so we never see it. I came across it because I've been working on better error reporting and the changes pick up this error. To make sure it wasn't my code I removed all of my error handling code and put only the following at the top of dblog_watchdog():

file_put_contents('trace.txt', __FILE__ .': ' .__LINE__ . ': ' . __FUNCTION__ . ': var message: ' . $log_entry['message'] ."\n", FILE_APPEND);

and sure enough the error message got written to the trace file. It gets silently ignored because Drupal tries to write the except to the DB which PHP won't allow (PDOExceptions cannot be written to the DB) and there's some code to prevent reporting errors within the error reporting to prevent a runaway script.

My new code makes sure we see these errors along a few other benefits. This discovery is from the latest patch in this issue: https://www.drupal.org/node/1158322#comment-10519622 .

Currently there is a workaround in the patch which is below:

/**
 * Implements hook_watchdog().
 *
 * Note: Some values may be truncated to meet database column size restrictions.
 */
function dblog_watchdog(array $log_entry) {
  if (!array_has_PDOException($log_entry)) { // If it was a DB error don't write to the DB.
    Database::getConnection('default', 'default')->insert('watchdog')
      ->fields(array(
        'uid'       => $log_entry['uid'],
        'type'      => substr($log_entry['type'], 0, 64),
        'message'   => $log_entry['message'],
        'variables' => serialize($log_entry['variables']),
        'severity'  => $log_entry['severity'],
        'link'      => substr($log_entry['link'], 0, 255),
        'location'  => $log_entry['request_uri'],
        'referer'   => $log_entry['referer'],
        'hostname'  => substr($log_entry['ip'], 0, 128),
        'timestamp' => $log_entry['timestamp'],
      ))
      ->execute();
  }
  else {
    // The following if statement is because the test "basic upgrade path" throws
    // the following error:
    //    SQLSTATE[42S02]: Base table or view not found: 1146 
    //    Table 'drupal_7_dev.simpletest107742access' doesn't exist: SELECT mask 
    //    FROM {access} WHERE status = :status AND type = :type; 
    //    Array ( [:status] => 0 [:type] => host ) 
    // however the existing Drupal error logging just let's it go without telling
    // simpletests there's a problem (because a calling function uses a simple
    // semaphore to stop errors being triggered inside the error handler). Since
    // we go out of our way to catch these errors as well we won't pass the
    // automatic tester while this error exists. 
    // 
    // To solve this we add the following if statement to more accurrately
    // simulate Drupal's current behavior. Once the SQL error in the test is
    // fixed we should remove this if statement.
    if (!drupal_valid_test_ua()) {
      _drupal_log_error($log_entry['variables'], TRUE);
    }
  }
}

Comments

Reg created an issue. See original summary.

nimbfire@gmail.com’s picture

The dblog module had an update. The function uses now drupal_substr instead of substr . This is the end code for me:

<?php
  if (!function_exists('drupal_substr')) {
    require_once DRUPAL_ROOT . '/includes/unicode.inc';
  }
  if (!array_has_PDOException($log_entry)) { // If it was a DB error don't write to the DB.
    Database::getConnection('default', 'default')->insert('watchdog')
      ->fields(array(
        'uid' => $log_entry['uid'],
        'type' => drupal_substr($log_entry['type'], 0, 64),
        'message' => $log_entry['message'],
        'variables' => serialize($log_entry['variables']),
        'severity' => $log_entry['severity'],
        'link' => drupal_substr($log_entry['link'], 0, 255),
        'location' => $log_entry['request_uri'],
        'referer' => $log_entry['referer'],
        'hostname' => drupal_substr($log_entry['ip'], 0, 128),
        'timestamp' => $log_entry['timestamp'],
      ))
      ->execute();
  }
  else {
    // The following if statement is because the test "basic upgrade path" throws
    // the following error:
    //    SQLSTATE[42S02]: Base table or view not found: 1146
    //    Table 'drupal_7_dev.simpletest107742access' doesn't exist: SELECT mask
    //    FROM {access} WHERE status = :status AND type = :type;
    //    Array ( [:status] => 0 [:type] => host )
    // however the existing Drupal error logging just let's it go without telling
    // simpletests there's a problem (because a calling function uses a simple
    // semaphore to stop errors being triggered inside the error handler). Since
    // we go out of our way to catch these errors as well we won't pass the
    // automatic tester while this error exists.
    //
    // To solve this we add the following if statement to more accurrately
    // simulate Drupal's current behavior. Once the SQL error in the test is
    // fixed we should remove this if statement.
    if (!drupal_valid_test_ua()) {
      _drupal_log_error($log_entry['variables'], TRUE);
    }
  }
?>

Status: Active » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.