Db-error.php et les erreurs SQL de WordPress

Publié le 12 juillet 2012 Les thèmes de WordPress

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.

Error establishing a database connection
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. 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 :

Message d'erreur personnalisé sur WordPress avec db-error.php
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>

Daniel Roch

Fondateur, conférencier, auteur, consultant et expert SEO WordPress

19 Commentaires

Cristophe Le 12 juillet 2012 à 11h12
Merci pour cet article ! Voilà qui sera pluss sympa pour le visiteur, tout en espérant que cela ne lui arrive pas. d:-)
stef Le 12 juillet 2012 à 11h27
C'est bon ca apres les pages 404 personalisées ;-)
djib's Le 13 juillet 2012 à 7h54
Moi perso à la place d'un message je mets le cache de google du coup ca ne me fait pas perdre de visiteurs.

[pastacode lang="bash" provider="manual"]$host=$_SERVER['HTTP_HOST'];
$uri=urlencode($_SERVER['REQUEST_URI']);
header("Location: http://google.com/search?q=cache:$host$uri");
exit();
[/pastacode]
Daniel Roch Le 13 juillet 2012 à 10h01
Excellente ton idée Djib's ;)
stef Le 13 juillet 2012 à 10h40
@Djib's : static.iphoneaddict.fr/A-propos moi ca j'aime bien aussi :-(

erreur 500
Vital.it Le 13 juillet 2012 à 11h41
Merci c'est très utile, surtout chez certains fournisseurs mutualisés!
J'avais déjà quelque chose en place, mais vraiment succint côté rapport d'erreur. Je viens d'améliorer ça.

Du coup j'aimerai intégrer la solution de Djib's à celle de Daniel mais je ne sait pas la coder. Ca donnerai au lecteur qqchose comme: "Revenez dans quelques minutes blabla… vous pouvez aussi cliquer ici pour voir si google a une copie de cette page."

Car j'ai des pages que je ne souhaite pas "cacher", dans ce cas le redirect strict de Djib's peut donner quelquechose d'indigeste, non?

Comment peut-on faire ça svp?
Merci.
Djib's Le 13 juillet 2012 à 13h09
merci :-)
Cristophe Le 13 juillet 2012 à 13h10
Bien cette idée d'utiliser le cache de google.
Je voudrais afficher le message tel que expliqué dans l'article, et ajouter ensuite :
"Vous pouvez consulter le cache de google : " + le lien vers ce cache.
~~~~~~~
En tant que néophyte, je ne sais pas comment faire. Quelqu'un pourrait-il me donner le code ?
djib's Le 14 juillet 2012 à 22h26
@stef
merci c'est corrigé
Gwaradenn Le 17 juillet 2012 à 8h51
Cristophe, il suffit de l'ajouter dans la div "wrapper" au format HTML :
Vous pouvez consulter le cache de google : [pastacode lang="bash" provider="manual"]<a href="URLDUCACHE" rel="nofollow">ICI</a>.[/pastacode]
master case Le 24 juillet 2012 à 12h43
Super idée Djibs pour l'affichage du cache google :) moi qui me contentais jusque là d'un message inquiétant, j'avais jamais pensé à faire ça :D
shaza Le 11 novembre 2012 à 2h15
Personnellement, je renvoie vers une version statique, pour ne pas perdre de visiteur
[pastacode lang="bash" provider="manual"]<?php
header('HTTP/1.1 503 Service Temporarily Unavailable');
header('Status: 503 Service Temporarily Unavailable');
$host="http://".$_SERVER['HTTP_HOST'];
$host.="/mirror".$_SERVER['REQUEST_URI'];
$host2=="http://".$_SERVER['HTTP_HOST'];
$host2.=$_SERVER['REQUEST_URI'];
[/pastacode]

$host2 me permet de savoir sur quelle page s'est produite l'erreur et $host me permet de rediriger vers la page statique correspondante, pour l'utilisateur ça se fait de manière quasi transparente...
Jeremy Le 20 juillet 2018 à 8h07
Bonjour,

Pour ma part quand je mets cette page en place, j'obtiens une page blanche quand je m'amuse à modifier wp-config afin de vérifier si ça fonctionne. Est-ce normal ? Car sinon sans la page j'obtiens bien le premier message cité. Dois-je configurer quelque chose ?
Jeremy Le 20 juillet 2018 à 8h21
Bonjour,

J'ai trouvé la solution à mon problème. C'était du à PHP7 qui ne prend plus en charge "mysql_error" il faut donc modifier en "mysqli_error" c'est tout !
    Daniel Roch Le 20 juillet 2018 à 9h10
    Merci pour la solution.
Julianinho Le 13 septembre 2019 à 18h33
Bonjour,

Merci pour cet article car de mon côté je tombe souvent sur ce message "error establising a database connection" par moment et aléatoirement lorsque je vais sur mon site.
Ce problème est apparu depuis la migration d'ovh vers o2switch.
J'ai contacté o2switch qui me confirme que la bdd est fonctionnelle et non corrompue.
Pour eux le soucis viendrait d'un plugin ou du thème, le problème c'est qu'il est impossible de trouver le fautif comme plugin car dès que je tombe sur "error establising a database connection", il suffit de réactualiser la page pour que ça refonctionne du coup on à pas le temps d'aller jusqu'à la page des plugins et les désactiver.
    Daniel Roch Le 15 septembre 2019 à 9h57
    Cela peut venir de plein de choses, de l'hébergeur, de la base de données, d'un code non optimisé dans le thème et ou une extension. Dans ce cas, il faut auditer le site pour comprendre l'origine de ces erreurs de la base de données.
Julianinho Le 15 septembre 2019 à 21h23
Bonsoir,

Merci pour votre réponse.
Connaissez vous des sites qui permettent de faire ce genre d'audit ou faut il le faire manuellement ?

Bonne soirée
    Daniel Roch Le 16 septembre 2019 à 9h29
    Il n'existe malheureusement pas de site pour faire cela, il faut faire appel à un prestataire. Nous pouvons vous accompagner sur ce sujet chez SeoMix ;)

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *