I've created the following patch to allow developers to specify a custom function name in $db_error_handler variable in settings.php to override the default database error behavior.

I've tested this on mysql:// and pgsql:// database connections with flying colors. I have not yet tested against mysqli:// for lack of a php module, so that bit needs review.

Also, please let me know if it would be helpful to provide a version of this patch for Drupal 6.

Comments

IncrediblyKenzi’s picture

As a side note, the patch also includes a custom implementation (commented out) in settings.php.

boris mann’s picture

Status: Needs review » Closed (won't fix)

Setting this to "won't fix", since that was the agreed method for providing backports / features in older versions.

Aaron, please re-roll against HEAD, not including the custom implementation in settings.php (just include that in your comment / description), and create a new issue for it. Thanks!

webchick’s picture

Version: 5.1 » 6.x-dev
Status: Closed (won't fix) » Needs work

Woah, this is a great little feature! Don't won't fix it until we get it in 6. :)

Benefits:
- Right now the word "Drupal" is hard-coded in these error messages. Particularly troublesome if you're trying to mask what platform you're running your site on for security reasons (yes, security by obscurity, but still... no sense in handing someone a golden key) or if you have your own distribution called SuperCheese.
- You're also spitting sensitive database information to the general public. And unlike regular error stuff that happens which you can select under error handling to not show on screen, this will show up for everyone who views your site. Silliness.

The only thing I'm not crazy about is requiring putting this in settings.php, simply because in the case of a multisite installation you'll have 40,000 of those. Is there another place it could go?

webchick’s picture

Also, it might be worth giving all lack-of-db-related errors this treatment... ex: unsupported database type, PHP support not enabled, can't select database, install/update messages.

webchick’s picture

StatusFileSize
new16.02 KB

Here's another approach... note that this doesn't actually work yet. ;)

webchick’s picture

The idea, though, is you place a custom function somewhere (probably settings.php, but could also be hacked into bootstrap.inc for multisite installs):

/**
 * Custom error handler.
 */
function custom_offline_error_handler($id, $error) {
  if ($id == 'db-connect') {
    $error['error'] = 'Please try again later.';
    mail('admin@example.com', 'Fix the db!', $error);
  }

  return $error;
}
webchick’s picture

From chx:

if (!function_exists('custom_offline_error_handler') || !($error = custom_offline_error_handler($id))) {
// put switch here
}
IncrediblyKenzi’s picture

I'm actually a fan of that.. far better to have a predefined function name rather than relying on a modified template-method pattern to define a custom function name... Much simpler :)

I'll re-roll against HEAD now, assuming that the function should live in settings.php.

IncrediblyKenzi’s picture

StatusFileSize
new19.41 KB

Here's the latest (see attached patch), fixes applied against HEAD.

I opted for a hybrid of the two.. Your switch statements are all in there, but by default they're handled each by their respective database engine.

IncrediblyKenzi’s picture

As for where the custom function should live, well, I'm open to suggestions.

I had assumed that the majority of sites would want to theme their error pages slightly differently (especially in the case of multisite installs), so settings.php is still the right spot, methinks.

IncrediblyKenzi’s picture

Status: Needs work » Needs review

changing status to "code needs review," since it does ;)

kbahey’s picture

I like this concept.

+1.

Here is another approach. Not sure what people think.

It is along the lines of how the caching .inc file is pluggable via a $conf variable that points to an alternate file to use (see bootstrap.inc):

function _drupal_cache_init($phase) {
  require_once variable_get('cache_inc', './includes/cache.inc');

This can be done but not straightforward. We need to do:

$db_inc = variable_get('db_inc', './includes/db_' .$_GLOBALS['db_type']. '.inc');
// check if file exists first, then
require_once $db_inc;

This way, we have a default handler for each db_type (or maybe no handler, but sites can override it by custom stuff. A site would use one db type, so they only need one .inc.

What do people think?

dmitrig01’s picture

-1 to killes' approach

kbahey’s picture

killes did not comment here. You mean kbahey? They are so different you know? ;-)

dmitrig01’s picture

LOL sorry I mean kbahey (I was talking to killes on IRC while posting this) I don't like your approach 'cause that defeats the purpose of db_set_active. (hint: look @ the docs for that)

catch’s picture

Version: 6.x-dev » 7.x-dev
Status: Needs review » Needs work

No longer applies, bumping to Drupal 7

Crell’s picture

Is this still necessary given the new DB API? Error handling is now via exceptions, so it's an entirely different animal.

IncrediblyKenzi’s picture

I think it still applies.. Ideally the exception handler should be customizable. Open to hearing more on that, however.

senpai’s picture

Status: Needs work » Postponed (maintainer needs more info)

There was a move underfoot to provide D7 with a completely themable "database error, site offline" message. Doesn't that negate this approach? Having just skimmed this patch (#9) I find that it's trying to change the default output of a db_error and allow it to be overridden. Right? Seems to me that the themable site offline movement would handle this as well.

jlambert’s picture

I don't think that's the use case necessarily.

Imagine if you had an error condition you wanted to display to user. Would you throw up the database error, "Access denied for user 'xx'@'x.x.x.x' to database 'xxx'". This isn't friendly, and reveals a LOT of information which you probably don't want to advertise.

An override patch like this (which might even be considered a default), would be to attach an error condition, could put up something like, "We're sorry, a database error occurred, therefore masking the error (nice for security), and maybe dropping some kind of ticket into my helpdesk to let me know that things are busting up something serious. :) That's very different from a site offline.

$db_inc = variable_get('db_inc', './includes/db_' .$_GLOBALS['db_type']. '.inc');
// check if file exists first, then
require_once $db_inc;

The only problem I have with this is that this evaluation is being done on every database request. This could have some implications for larger sites, where, at least from a performance standpoint (and Drupal needs it), simple would be better. The idea is great, I'm just wondering if there is a less expensive way to write it.

sun.core’s picture

Priority: Normal » Critical
Status: Postponed (maintainer needs more info) » Needs work

Given the last comment, this is at least critical. Perhaps. Let's ensure and prove it's not.

Crell’s picture

Version: 7.x-dev » 8.x-dev

This is a feature request, so I'm going to bump it to Drupal 8. If someone from the security team wants to push it back to Drupal 7, make sure Drieschick will let us work on it at this stage of the game before doing so. :-) I'll defer to Drieschick/security folks here.

catch’s picture

Priority: Critical » Major

Downgrading all D8 criticals to major per http://drupal.org/node/45111

jhedstrom’s picture

Version: 8.0.x-dev » 8.1.x-dev
Issue summary: View changes

Probably 8.1 at least.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

gagarine’s picture

Version: 9.5.x-dev » 10.1.x-dev

Is this still relevant?
I stumble on this after being surprised that when your DB server is down you get a blank page with error instead of some nicer page.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.