From da7c9547ae65e4228b5e682e827061a62d50fdd0 Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Mon, 4 Aug 2008 05:44:37 +0000
Subject: [PATCH] Added error framework based on exceptions.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@793 44740490-163a-0410-bde0-09ae8108e29a
---
 dictionaries/errors.php            | 48 +++++++++++++++
 lib/SimpleSAML/Error/Assertion.php | 90 +++++++++++++++++++++++++++
 lib/SimpleSAML/Error/Error.php     | 97 ++++++++++++++++++++++++++++++
 lib/SimpleSAML/Error/NotFound.php  | 64 ++++++++++++++++++++
 4 files changed, 299 insertions(+)
 create mode 100644 lib/SimpleSAML/Error/Assertion.php
 create mode 100644 lib/SimpleSAML/Error/Error.php
 create mode 100644 lib/SimpleSAML/Error/NotFound.php

diff --git a/dictionaries/errors.php b/dictionaries/errors.php
index c99196322..aa468a98a 100644
--- a/dictionaries/errors.php
+++ b/dictionaries/errors.php
@@ -972,6 +972,54 @@ $lang = array(
 		'hr' => 'Informacija o tekućem zahtjevu za odjavljivanjem se izgubila. Preporučamo da se vratite u aplikaciju iz koje ste se htjeli odjaviti i pokušate se odjaviti ponovo. Ova greška može biti uzrokovana istekom valjanosti zahtjeva za odjavom. Zahtjev se pohranjuje određeno vrijeme - u pravilu nekoliko sati. Obzirom da je to dulje nego što bi bilo koja operacija odjavljivanja trebala trajati, greška koja se pojavila može upućivati na grešku u konfiguraciji. Ako se problem nastavi, kontaktirajte vašeg davatelja usluge. ',
 		'hu' => 'A kijelentkezési művelettel kapcsolatos információk valahol elvesztek. Kérjük, térjen vissza ahhoz a szolgáltatáshoz, ahonnan ki akart jelentkezni, és próbálja újra! Lehetséges, hogy a hibát az okozza, hogy a kijelentkezéshez szükséges információ elévült. A kijelentkezési információ csak korlátozott ideig érvényes - általában néhány óráig. Ez hosszabb, mint amennyi normális esetben a kijelentkezéshez szükséges, ezért ez a hibaüzenet konfigurációs hibát jelenthet. Ha a probléma továbbra is fennáll, kérjük, forduljon az alkalmazásszolgáltatóhoz (SP)!',
 	),
+	'title_ASSERTFAIL' => array (
+		'en' => 'Assertion failure',
+		'es' => 'Error en la afirmaciĂłn (Assertion)',
+		'sl' => 'Neveljavna zahteva',
+		'hu' => 'Igazolás (assertion) hiba',
+	),
+	'descr_ASSERTFAIL' => array (
+		'en' => 'An assertion in the code failed. The assertion was: %ASSERTION%',
+		'es' => 'Una afirmaciĂłn del cĂłdigo ha fallado. La afirmaciĂłn es: %ASSERTION%',
+		'sl' => 'Vnos v kodo je spodletel. Navedena je bila naslednja zahteva: %ASSERTION%',
+		'hu' => 'Igazolás (assetion) hiba a kódban. A hibás igazolás: %ASSERTION%',
+	),
+	'title_UNHANDLEDEXCEPTION' => array (
+		'en' => 'Unhandled exception',
+		'es' => 'ExcepciĂłn no controlada',
+		'sl' => 'Nedefinirana izjema.',
+		'hu' => 'Kezeletlen kivétel',
+	),
+	'descr_UNHANDLEDEXCEPTION' => array (
+		'en' => 'An unhandled exception was thrown.',
+		'es' => 'Se lanzĂł una excepciĂłn no controlada.',
+		'sl' => 'Zagnana je bila nedefinirana izjema.',
+		'hu' => 'Kezeletlen kivétel keletkezett.',
+	),
+	'title_NOTFOUND' => array (
+		'en' => 'Page not found',
+		'es' => 'Página no encontrada',
+		'sl' => 'Strani ni bilo mogoÄŤe najti.',
+		'hu' => 'Oldal nem található',
+	),
+	'descr_NOTFOUND' => array (
+		'en' => 'The given page was not found. The URL was: %URL%',
+		'es' => 'La página que indicó no se encontró. La URL es: %URL%',
+		'sl' => 'Strani ni bilo mogoÄŤe najti. Naveden URL strani je bil: %URL%',
+		'hu' => 'Az alábbi oldal nem található: %URL%',
+	),
+	'title_NOTFOUNDREASON' => array (
+		'en' => 'Page not found',
+		'es' => 'Página no encontrada',
+		'sl' => 'Strani ni bilo mogoÄŤe najti.',
+		'hu' => 'Oldal nem található',
+	),
+	'descr_NOTFOUNDREASON' => array (
+		'en' => 'The given page was not found. The reason was: %REASON%  The URL was: %URL%',
+		'es' => 'La página que indicó no se encontró. El motivo es: %REASON% La URL es: %URL%',
+		'sl' => 'Strani ni bilo mogoÄŤe najti. Razlog: %REASON%. Naveden URL strani je bil: %URL%',
+		'hu' => '%URL% oldal nem található, a következő ok miatt: %REASON% ',
+	),
 
 );
 
diff --git a/lib/SimpleSAML/Error/Assertion.php b/lib/SimpleSAML/Error/Assertion.php
new file mode 100644
index 000000000..ef4fc0e56
--- /dev/null
+++ b/lib/SimpleSAML/Error/Assertion.php
@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * Class for creating exceptions from assertion failures.
+ *
+ * @author Olav Morken, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class SimpleSAML_Error_Assertion extends SimpleSAML_Error_Error {
+
+
+	/**
+	 * The assertion which failed, or NULL if only an expression was passed to the
+	 * assert-function.
+	 */
+	private $assertion;
+
+
+	/**
+	 * Constructor for the assertion exception.
+	 *
+	 * Should only be called from the onAssertion handler.
+	 *
+	 * @param string|NULL $assertion  The assertion which failed, or NULL if the assert-function was
+	 *                                given an expression.
+	 */
+	public function __construct($assertion = NULL) {
+		assert('is_null($assertion) || is_string($assertion)');
+
+		parent::__construct(array('ASSERTFAIL', '%ASSERTION%' => var_export($assertion, TRUE)));
+
+		$this->assertion = $assertion;
+	}
+
+
+	/**
+	 * Retrieve backtrace from where the assert-function was called.
+	 *
+	 * @return array  Array with a backtrace. Each element is a string which identifies a position
+	 *                in the source.
+	 */
+	public function getAssertionBacktrace() {
+		return SimpleSAML_Utilities::buildBacktrace($this, 2);
+	}
+
+
+	/**
+	 * Retrieve the assertion which failed.
+	 *
+	 * @return string|NULL  The assertion which failed, or NULL if the assert-function was called with an expression.
+	 */
+	public function getAssertion() {
+		return $this->assertion;
+	}
+
+
+	/**
+	 * Install this assertion handler.
+	 *
+	 * This function will register this assertion handler. If will not enable assertions if they are
+	 * disabled.
+	 */
+	public static function installHandler() {
+		assert_options(ASSERT_WARNING,    0);
+		assert_options(ASSERT_BAIL,       0);
+		assert_options(ASSERT_QUIET_EVAL, 0);
+		assert_options(ASSERT_CALLBACK,   array('SimpleSAML_Error_Assertion', 'onAssertion'));
+	}
+
+
+	/**
+	 * Handle assertion.
+	 *
+	 * This function handles an assertion.
+	 *
+	 * @param string $file  The file assert was called from.
+	 * @param int $line  The line assert was called from.
+	 * @param mixed $message  The expression which was passed to the assert-function.
+	 */
+	public static function onAssertion($file, $line, $message) {
+
+		if(!empty($message)) {
+			throw new self($message);
+		} else {
+			throw new self();
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/lib/SimpleSAML/Error/Error.php b/lib/SimpleSAML/Error/Error.php
new file mode 100644
index 000000000..30a6897b0
--- /dev/null
+++ b/lib/SimpleSAML/Error/Error.php
@@ -0,0 +1,97 @@
+<?php
+
+/**
+ * Class which wraps simpleSAMLphp errors in exceptions.
+ *
+ * @author Olav Morken, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class SimpleSAML_Error_Error extends Exception {
+
+
+	/**
+	 * The error code.
+	 */
+	private $errorCode;
+
+
+	/**
+	 * The exception which caused this error.
+	 */
+	private $cause;
+
+
+	/**
+	 * Constructor for this error.
+	 *
+	 * The error can either be given as a string, or as an array. If it is an array, the
+	 * first element in the array (with index 0), is the error code, while the other elements
+	 * are replacements for the error text.
+	 *
+	 * @param mixed $errorCode  One of the error codes defined in the errors dictionary.
+	 * @param Exception $cause  The exception which caused this fatal error (if any).
+	 */
+	public function __construct($errorCode, Exception $cause = NULL) {
+
+		assert('is_string($errorCode) || is_array($errorCode)');
+
+		$this->errorCode = $errorCode;
+		$this->cause = $cause;
+	}
+
+
+	/**
+	 * Retrieve the error code given when throwing this error.
+	 *
+	 * @return mixed  The error code.
+	 */
+	public function getErrorCode() {
+		return $this->errorCode;
+	}
+
+
+	/**
+	 * Retrieve the exception which caused this error.
+	 *
+	 * @return Exception  The exception which caused this error, or NULL if no exception caused this error.
+	 */
+	public function getCause() {
+		return $this->cause;
+	}
+
+
+	/**
+	 * Set the HTTP return code for this error.
+	 *
+	 * This should be overridden by subclasses who want a different return code than 500 Internal Server Error.
+	 */
+	protected function setHTTPCode() {
+		header('HTTP/1.0 500 Internal Server Error');
+	}
+
+
+	/**
+	 * Display this error.
+	 *
+	 * This method displays a standard simpleSAMLphp error page and exits.
+	 */
+	public function show() {
+
+		$this->setHTTPCode();
+
+		$session = SimpleSAML_Session::getInstance();
+
+		if($this->cause !== NULL) {
+			$e = $this->cause;
+		} else {
+			$e = $this;
+		}
+
+		SimpleSAML_Utilities::fatalError($session->getTrackID(), $this->errorCode, $e);
+
+	}
+
+}
+
+?>
\ No newline at end of file
diff --git a/lib/SimpleSAML/Error/NotFound.php b/lib/SimpleSAML/Error/NotFound.php
new file mode 100644
index 000000000..fd2406760
--- /dev/null
+++ b/lib/SimpleSAML/Error/NotFound.php
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * Exception which will show a 404 Not Found error page.
+ *
+ * This exception can be thrown from within an module page handler. The user will then be
+ * shown a 404 Not Found error page.
+ *
+ * @author Olav Morken, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class SimpleSAML_Error_NotFound extends SimpleSAML_Error_Error {
+
+
+	/**
+	 * Reason why the given page could not be found.
+	 */
+	private $reason;
+
+
+	/**
+	 * Create a new NotFound error
+	 *
+	 * @param string $reason  Optional description of why the given page could not be found.
+	 */
+	public function __construct($reason = NULL) {
+
+		assert('is_null($reason) || is_string($reason)');
+
+		$url = SimpleSAML_Utilities::selfURL();
+
+		if($reason === NULL) {
+			parent::__construct(array('NOTFOUND', '%URL%' => $url));
+		} else {
+			parent::__construct(array('NOTFOUNDREASON', '%URL%' => $url, '%REASON%' => $reason));
+		}
+
+		$this->reason = $reason;
+	}
+
+
+	/**
+	 * Retrieve the reason why the given page could not be found.
+	 *
+	 * @return string|NULL  The reason why the page could not be found.
+	 */
+	public function getReason() {
+		return $this->reason;
+	}
+
+
+	/**
+	 * Set the HTTP return code for this error.
+	 *
+	 * This should be overridden by subclasses who want a different return code than 500 Internal Server Error.
+	 */
+	protected function setHTTPCode() {
+		header('HTTP/1.0 404 Not Found');
+	}
+
+}
+
+?>
\ No newline at end of file
-- 
GitLab