From 7f6d1063f7543f8e6c0e775dccdeff18626534cc Mon Sep 17 00:00:00 2001 From: Florent Bruneau Date: Fri, 2 Jul 2010 15:48:06 +0200 Subject: [PATCH] Manage site errors using exceptions. This has 3 main avantages: - Error may not be fatal (e.g. a SQL error must not be fatal during the execution of the unit tests) - We can have the backtrace - The same code handle all the kind of errors. Signed-off-by: Florent Bruneau --- classes/platal.php | 45 ++++++++------ classes/plexception.php | 36 +++++++++++ classes/xdb.php | 45 ++++---------- include/test.inc.php | 1 - modules/core.php | 28 +++------ templates/{assert_errors.tpl => site_errors.tpl} | 76 ++++++++++++------------ templates/sql_errors.tpl | 38 ------------ 7 files changed, 123 insertions(+), 146 deletions(-) create mode 100644 classes/plexception.php rename templates/{assert_errors.tpl => site_errors.tpl} (94%) delete mode 100644 templates/sql_errors.tpl diff --git a/classes/platal.php b/classes/platal.php index 06002ed..b911828 100644 --- a/classes/platal.php +++ b/classes/platal.php @@ -360,18 +360,35 @@ abstract class Platal $this->path = 'index'; } - $page->assign('platal', $this); - switch ($this->call_hook($page)) { - case PL_FORBIDDEN: - $this->mods['core']->handler_403($page); - break; + try { + $page->assign('platal', $this); + switch ($this->call_hook($page)) { + case PL_FORBIDDEN: + $this->mods['core']->handler_403($page); + break; + + case PL_NOT_FOUND: + $this->mods['core']->handler_404($page); + break; + + case PL_WIKI: + return PL_WIKI; + } + } catch (Exception $e) { + header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error'); - case PL_NOT_FOUND: - $this->mods['core']->handler_404($page); - break; + $file = fopen(self::globals()->spoolroot . '/spool/tmp/site_errors', 'a'); + fwrite($file, '
' . date('Y-m-d G:i:s') . '
' + . '
' . pl_entities("" . $e) . '
' + . '------------------------------------------------------------------' . "\n"); + fclose($file); - case PL_WIKI: - return PL_WIKI; + if (self::globals()->debug) { + $page->kill(pl_entities($e->getMessage()) + . '
' . pl_entities("" . $e) . '
'); + } else { + $page->kill(pl_entities($e->getMessage())); + } } $page->assign('platal', $this); @@ -426,19 +443,13 @@ abstract class Platal public static function assert($cond, $error, $userfriendly = null) { - global $globals; if ($cond === false) { - header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error'); - $file = fopen($globals->spoolroot . '/spool/tmp/assert_erros', 'a'); - fwrite($file, '
' . pl_entities($error) . '
\n'); - fclose($file); - if ($userfriendly == null) { $userfriendly = "Une erreur interne s'est produite. Merci de réessayer la manipulation qui a déclenché l'erreur ; si cela ne fonctionne toujours pas, merci de nous signaler le problème rencontré."; } - Platal::page()->kill($userfriendly); + throw new PlException($userfriendly, $error); } } diff --git a/classes/plexception.php b/classes/plexception.php new file mode 100644 index 0000000..b819fc1 --- /dev/null +++ b/classes/plexception.php @@ -0,0 +1,36 @@ +internalMessage = $internalMessage; + } + + public function __toString() { + return $this->internalMessage . "\n\n" . parent::__toString(); + } +} + +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: +?> diff --git a/classes/xdb.php b/classes/xdb.php index 6a15660..6ceb911 100644 --- a/classes/xdb.php +++ b/classes/xdb.php @@ -19,10 +19,21 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * **************************************************************************/ +class XDBException extends PlException { + public function __construct($query, $error) { + if (strpos($query, 'INSERT') === false && strpos($query, 'UPDATE') === false + && strpos($query, 'REPLACE') === false && strpos($query, 'DELETE') === false) { + $text = 'Erreur lors de l\'interrogation de la base de données'; + } else { + $text = 'Erreur lors de l\'écriture dans la base de données'; + } + parent::__construct($text, $query . "\n" . $error); + } +} + class XDB { private static $mysqli = null; - private static $fatalErrors = true; public static function connect() { @@ -40,11 +51,6 @@ class XDB return true; } - public static function setNonFatalError() - { - self::$fatalErrors = false; - } - public static function _prepare($args) { global $globals; @@ -113,32 +119,7 @@ class XDB } if ($res === false) { - header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error'); - if (strpos($query, 'INSERT') === false && strpos($query, 'UPDATE') === false - && strpos($query, 'REPLACE') === false && strpos($query, 'DELETE') === false) { - $text = 'Erreur lors de l\'interrogation de la base de données'; - } else { - $text = 'Erreur lors de l\'écriture dans la base de données'; - } - if (php_sapi_name() == 'cli') { - $text .= "\n" . XDB::_reformatQuery($query) - . "\n" . XDB::$mysqli->error; - } else if ($globals->debug) { - $text .= '
' . pl_entities(XDB::_reformatQuery($query)) . '
'; - } else { - $file = fopen($globals->spoolroot . '/spool/tmp/query_errors', 'a'); - fwrite($file, '
' . date("Y-m-d G:i:s") . '
' - . '
' . pl_entities(XDB::_reformatQuery($query)) . '
' - . '
' . XDB::$mysqli->error . '
' - . "--------------------------------------------------------------------------------\n"); - fclose($file); - } - if (self::$fatalErrors) { - Platal::page()->kill($text); - exit; - } else { - throw new Exception($text . " :\n" . $query); - } + throw new XDBException(XDB::_reformatQuery($query), XDB::$mysqli->error); } return $res; } diff --git a/include/test.inc.php b/include/test.inc.php index c5dc418..2a7048e 100644 --- a/include/test.inc.php +++ b/include/test.inc.php @@ -31,7 +31,6 @@ if (file_exists($testinclude)) { pl_autoload($class); } } -XDB::setNonFatalError(); // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: ?> diff --git a/modules/core.php b/modules/core.php index adbcf38..6d43027 100644 --- a/modules/core.php +++ b/modules/core.php @@ -30,8 +30,9 @@ class CoreModule extends PLModule 'send_bug' => $this->make_hook('bug', AUTH_COOKIE), 'purge_cache' => $this->make_hook('purge_cache', AUTH_COOKIE, 'admin'), 'kill_sessions' => $this->make_hook('kill_sessions', AUTH_COOKIE, 'admin'), - 'sql_errors' => $this->make_hook('sqlerror', AUTH_COOKIE, 'admin'), - 'assert_errors' => $this->make_hook('asserterror', AUTH_COOKIE, 'admin'), + 'sql_errors' => $this->make_hook('siteerror', AUTH_COOKIE, 'admin'), + 'assert_errors' => $this->make_hook('siteerror', AUTH_COOKIE, 'admin'), + 'site_errors' => $this->make_hook('siteerror', AUTH_COOKIE, 'admin'), 'wiki_help' => $this->make_hook('wiki_help', AUTH_PUBLIC), 'wiki_preview' => $this->make_hook('wiki_preview', AUTH_COOKIE, 'user', NO_AUTH), @@ -177,29 +178,16 @@ class CoreModule extends PLModule exit; } - function handler_sqlerror(&$page) { + function handler_siteerror(&$page) { global $globals; - $page->coreTpl('sql_errors.tpl'); - $file = @file_get_contents($globals->spoolroot . '/spool/tmp/query_errors'); + $page->coreTpl('site_errors.tpl'); + $file = @file_get_contents($globals->spoolroot . '/spool/tmp/site_errors'); if ($file !== false) { $page->assign('errors', utf8_encode($file)); } if (Post::has('clear')) { - @unlink($globals->spoolroot . '/spool/tmp/query_errors'); - $page->trigSuccess("Erreurs MySQL effacées."); - } - } - - function handler_asserterror(&$page) { - global $globals; - $page->coreTpl('assert_errors.tpl'); - $file = @file_get_contents($globals->spoolroot . '/spool/tmp/assert_errors'); - if ($file !== false) { - $page->assign('errors', utf8_encode($file)); - } - if (Post::has('clear')) { - @unlink($globals->spoolroot . '/spool/tmp/assert_errors'); - $page->trigSuccess("Erreurs d'assertion effacées."); + @unlink($globals->spoolroot . '/spool/tmp/site_errors'); + $page->trigSuccess("Erreurs effacées."); } } } diff --git a/templates/assert_errors.tpl b/templates/site_errors.tpl similarity index 94% rename from templates/assert_errors.tpl rename to templates/site_errors.tpl index 058a5cf..ffdf1e5 100644 --- a/templates/assert_errors.tpl +++ b/templates/site_errors.tpl @@ -1,38 +1,38 @@ -{**************************************************************************} -{* *} -{* Copyright (C) 2003-2010 Polytechnique.org *} -{* http://opensource.polytechnique.org/ *} -{* *} -{* This program is free software; you can redistribute it and/or modify *} -{* it under the terms of the GNU General Public License as published by *} -{* the Free Software Foundation; either version 2 of the License, or *} -{* (at your option) any later version. *} -{* *} -{* This program is distributed in the hope that it will be useful, *} -{* but WITHOUT ANY WARRANTY; without even the implied warranty of *} -{* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *} -{* GNU General Public License for more details. *} -{* *} -{* You should have received a copy of the GNU General Public License *} -{* along with this program; if not, write to the Free Software *} -{* Foundation, Inc., *} -{* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *} -{* *} -{**************************************************************************} - -

Erreurs d'assertions

-

- {if $errors} - {$errors|smarty:nodefaults} - {else} - Il n'y a pas d'erreurs actuellement recensées. - {/if} -

-
-
- -
-
- - -{* vim:set et sws=2 sts=2 sw=2 enc=utf-8: *} +{**************************************************************************} +{* *} +{* Copyright (C) 2003-2010 Polytechnique.org *} +{* http://opensource.polytechnique.org/ *} +{* *} +{* This program is free software; you can redistribute it and/or modify *} +{* it under the terms of the GNU General Public License as published by *} +{* the Free Software Foundation; either version 2 of the License, or *} +{* (at your option) any later version. *} +{* *} +{* This program is distributed in the hope that it will be useful, *} +{* but WITHOUT ANY WARRANTY; without even the implied warranty of *} +{* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *} +{* GNU General Public License for more details. *} +{* *} +{* You should have received a copy of the GNU General Public License *} +{* along with this program; if not, write to the Free Software *} +{* Foundation, Inc., *} +{* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *} +{* *} +{**************************************************************************} + +

Erreurs d'exécution

+ {if $errors} + {$errors|smarty:nodefaults} + {else} +

+ Il n'y a pas d'erreurs actuellement recensées. +

+ {/if} +
+
+ +
+
+ + +{* vim:set et sws=2 sts=2 sw=2 enc=utf-8: *} diff --git a/templates/sql_errors.tpl b/templates/sql_errors.tpl deleted file mode 100644 index 7c67ce5..0000000 --- a/templates/sql_errors.tpl +++ /dev/null @@ -1,38 +0,0 @@ -{**************************************************************************} -{* *} -{* Copyright (C) 2003-2010 Polytechnique.org *} -{* http://opensource.polytechnique.org/ *} -{* *} -{* This program is free software; you can redistribute it and/or modify *} -{* it under the terms of the GNU General Public License as published by *} -{* the Free Software Foundation; either version 2 of the License, or *} -{* (at your option) any later version. *} -{* *} -{* This program is distributed in the hope that it will be useful, *} -{* but WITHOUT ANY WARRANTY; without even the implied warranty of *} -{* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *} -{* GNU General Public License for more details. *} -{* *} -{* You should have received a copy of the GNU General Public License *} -{* along with this program; if not, write to the Free Software *} -{* Foundation, Inc., *} -{* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *} -{* *} -{**************************************************************************} - -

Erreurs MySQL

- {if $errors} - {$errors|smarty:nodefaults} - {else} -

- Il n'y a pas d'erreurs actuellement recensées. -

- {/if} -
-
- -
-
- - -{* vim:set et sws=2 sts=2 sw=2 enc=utf-8: *} -- 2.1.4