Db-error.php et les erreurs SQL de WordPress

Publié le 12 juillet 2012 par Seomix @rochdaniel

Quel que soit la solution technique utilisée, il peut arriver que la base de données soit indisponible, empêchant ainsi l'internaute de visiter votre site

Sur WordPress, cela nous donne de magnifiques messages d'erreur, comme par exemple le magnifique "error establising a database connection". Et pourtant, le CMS nous permet à la fois de les personnaliser et de créer un système d'alerte en temps réel, le tout grâce à un simple petit fichier appelé db-error.php.

Les erreurs SQL

La base peut-être corrompue, le mot de passe a pu être changé, le serveur SQL peut mettre trop de temps à répondre, ... : il existe de nombreux types d'erreurs pour une base de données, et WordPress n'y échappe pas.

Ces erreurs s'affichent à la place de votre site, sans pour autant prévenir le webmaster ni donner de solutions pour l'internaute qui arrive sur votre site Internet.

Exemple d'erreur SQL

Le pire, c'est que souvent ces erreurs sont communes à toutes les pages. Ce n'est donc pas un seul contenu qui est inaccessible, mais bien toute votre site Internet.

Il existe en réalité des dizaines et des dizaines d'erreurs différentes (cf. cet article). D'ailleurs, il peut même s'agir d'erreurs SQL causées par de mauvais développements, et qui n'apparaissent que dans certains cas de figure (auquel cas vous avez le droit de flageller votre développeur).

Le fichier db-error.php

Et pourtant, WordPress a tout prévu. Quand votre base de données SQL ne répond pas, quel qu'en soit le motif, le CMS nous laisse la possibilité de gérer l'affichage de cette erreur avec le fichier db-error.php. Et mieux encore, cela nous permet de mettre en place un système automatisé pour prévenir le webmaster.

Signaler une erreur temporaire

La première étape est d'indiquer aux moteurs de recherche que le problème rencontré est temporaire avec un code 503, et de leur dire qu'ils peuvent essayer de nouveau de crawler le contenu d'ici dix minutes.

Pour cela, créez un fichier db-error.php dans le répertoire wp-content de votre installation WordPress, et copiez-y ce code :

<?php
$protocol = $_SERVER["SERVER_PROTOCOL"];
if ( 'HTTP/1.1' != $protocol & 'HTTP/1.0' != $protocol ) $protocol = 'HTTP/1.0';
header( "$protocol 503 Service Unavailable", true, 503 );
header( 'Content-Type: text/html; charset=utf-8' );
header( 'Retry-After: 600' );

On évite ainsi d'indexer des pages d'erreurs ou de freiner l'indexation d'un site qui rencontrerait en peu de temps un trop grand nombre d'erreurs.

Avertir le webmaster

La deuxième étape consiste à alerter la personne qui gère le site Internet. On capture donc deux informations :

  • $myerror : pour enregistrer l'erreur SQL rencontrée.
  • $myurl : pour enregistrer l'URL où l'erreur a été générée. Cela inclut à la fois le front-office du site et l'administration de WordPress.

Copiez à la suite le code suivant :

$myerror=mysql_error();
$myurl=curPageURL();
function curPageURL() {
 $pageURL = 'http';
 if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
 $pageURL .= "://";
 if ($_SERVER["SERVER_PORT"] != "80") {
  $pageURL .= $_SERVER["SERVER_NAME"]":"$_SERVER["SERVER_PORT"]$_SERVER["REQUEST_URI"];
 } else {
  $pageURL .= $_SERVER["SERVER_NAME"]$_SERVER["REQUEST_URI"];
 }
 return $pageURL;
}

Une fois ces deux informations trouvées, on peut envoyer un email au webmaster pour lui indiquer quel type d'erreur WordPress a rencontré au niveau de la base de données, et sur quelle page l'erreur s'est produite.

Là encore, copiez à la suite du fichier db-error.php ce nouveau code, en remplaçant MONSITE par le nom de votre site Internet et MONEMAIL par l'email de la personne à prévenir :

mail( 'MONEMAIL', 'Erreur SQL sur MONSITE', 'Ceci est un message automatis&eacute; suite &agrave; une erreur SQL rencontr&eacute; sur le site Internet. Le message est : '$myerror'. L\URL est : '$myurl);?>

Moins de quelques secondes après l'erreur, le webmaster est prévenu en temps réel.

Informer l'internaute

Enfin, nous pouvons changer le message qui s'affiche auprès de l'internaute. Au lieu d'avoir un message rébarbatif sans aucun sens, on peut afficher ce que l'on veut, comme par exemple ce simple message :

Un message d'erreur personnalisé sur WordPress avec db-error.php

Pour afficher ce type de message, copiez à la suite du fichier db-error.php le contenu suivant en remplaçant MONSITE par le nom de votre site WordPress (2 fois) :

<html>
<head>
    <title>MONSITE temporairement indisponible</title>
    <style>
        body{background:#fff;font:16px verdana, serif;line-height:1.3;margin:0;padding:0}
        #wrapper{height:225px;margin: 80px auto 0;width:575px}
        h1{font-size:34px;font-weight:normal;margin-top:0}
        p{margin:0 0 10px 5px}
    </style>
</head>
<body>
    <div id="wrapper">
        <h1>MONSITE est temporairement inaccessible.</h1>
        <p>Le webmaster du site a été averti. Merci de revenir plus tard.</p>
    </div>
</body>
</html>

Lorsque WordPress rencontre une erreur avec la base de données, il est fort possible que votre site soit entièrement indisponible. Je vous invite donc à étoffer ce message d'erreur en fonction de votre site Internet, avec par exemple :

  • Un lien vers vos profils sociaux
  • L'affichage d'une durée de "maintenance"

Revenez dans 24 heures

  • Une explication plus poussée de l'erreur
  • Des liens vers des partenaires ou d'autres sites du réseau
  • ...

Laissez libre court à votre imagination. Vous pouvez d'ailleurs très bien ajouter des images ou des vidéos si vous souhaitez faire patienter l'internaute.

Le code complet

Et pour les flemmards, voici le code complet du fichier db-error.php, qui je vous le rappelle se place dans le répertoire wp-content de WordPress. Pensez à remplacer l'email et les 3 occurrences du nom du site :

<?php
    $protocol = $_SERVER["SERVER_PROTOCOL"];
    if ( 'HTTP/1.1' != $protocol & 'HTTP/1.0' != $protocol ) $protocol = 'HTTP/1.0';
    header( "$protocol 503 Service Unavailable", true, 503 );
    header( 'Content-Type: text/html; charset=utf-8' );
    header( 'Retry-After: 600' );
    $temp=mysql_error();
    $url=curPageURL();
    function curPageURL() {
     $pageURL = 'http';
     if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
     $pageURL .= "://";
     if ($_SERVER["SERVER_PORT"] != "80") {
      $pageURL .= $_SERVER["SERVER_NAME"]":"$_SERVER["SERVER_PORT"]$_SERVER["REQUEST_URI"];
     } else {
      $pageURL .= $_SERVER["SERVER_NAME"]$_SERVER["REQUEST_URI"];
     }
     return $pageURL;
    }
    mail( 'MONEMAIL', 'Erreur SQL sur MONSITE', 'Ceci est un message automatis&eacute; suite &agrave; une erreur SQL rencontr&eacute; sur le site Internet. Le message est : '$temp'. L\URL est : '$url);
?>
<html>
<head>
    <title>MONSITE temporairement indisponible</title>
    <style>
        body{background:#fff;font:16px verdana, serif;line-height:1.3;margin:0;padding:0}
        #wrapper{height:225px;margin: 80px auto 0;width:575px}
        h1{font-size:34px;font-weight:normal;margin-top:0}
        p{margin:0 0 10px 5px}
    </style>
</head>
<body>
    <div id="wrapper">
        <h1>MONSITE est temporairement inaccessible.</h1>
        <p>Le webmaster du site a été averti Merci de revenir plus tard.</p>
    </div>
</body>
</html>