winter/modules/system/classes/ErrorHandler.php

130 lines
3.9 KiB
PHP
Raw Normal View History

2014-05-14 23:24:20 +10:00
<?php namespace System\Classes;
use App;
use View;
use Config;
use Request;
use Response;
use Cms\Classes\Theme;
use Cms\Classes\Router;
use Cms\Classes\Controller;
use System\Classes\BaseException;
use System\Classes\ApplicationException;
/**
* System Error Handler, this class handles application exception events.
*
* @package october\system
* @author Alexey Bobkov, Samuel Georges
*/
class ErrorHandler
{
/**
* @var System\Classes\ExceptionBase A prepared mask exception used to mask any exception fired.
*/
protected static $activeMask;
/**
* @var array A collection of masks, so multiples can be applied in order.
*/
protected static $maskLayers = [];
2014-05-14 23:24:20 +10:00
/**
* All exceptions are piped through this method from the framework workflow. This method will mask
2014-05-17 18:08:01 +02:00
* any foreign exceptions with a "scent" of the native application's exception, so it can render
2014-05-14 23:24:20 +10:00
* correctly when displayed on the error page.
* @param Exception $proposedException The exception candidate that has been thrown.
* @return View Object containing the error page.
*/
2014-09-20 17:56:59 +10:00
public function handleException(\Exception $proposedException, $httpCode = 500)
2014-05-14 23:24:20 +10:00
{
2014-09-20 17:56:59 +10:00
// Disable the error handler for test and CLI environment
2014-10-18 11:58:50 +02:00
if (App::runningUnitTests() || App::runningInConsole()) {
2014-05-14 23:24:20 +10:00
return;
2014-10-18 11:58:50 +02:00
}
2014-05-14 23:24:20 +10:00
// Detect AJAX request and use error 500
2014-10-18 11:58:50 +02:00
if (Request::ajax()) {
return Response::make($proposedException->getMessage(), $httpCode);
}
2014-05-14 23:24:20 +10:00
// Clear the output buffer
2014-10-18 11:58:50 +02:00
while (ob_get_level()) {
2014-05-14 23:24:20 +10:00
ob_end_clean();
2014-10-18 11:58:50 +02:00
}
2014-05-14 23:24:20 +10:00
// Friendly error pages are used
if (!Config::get('app.debug', false)) {
2014-05-14 23:24:20 +10:00
return $this->handleCustomError();
2014-10-18 11:58:50 +02:00
}
2014-05-14 23:24:20 +10:00
// If the exception is already our brand, use it.
if ($proposedException instanceof BaseException) {
$exception = $proposedException;
}
2014-11-01 12:03:38 +11:00
// If there is an active mask prepared, use that.
elseif (static::$activeMask !== null) {
2014-05-14 23:24:20 +10:00
$exception = static::$activeMask;
$exception->setMask($proposedException);
}
2014-11-01 12:03:38 +11:00
// Otherwise we should mask it with our own default scent.
else {
2014-05-14 23:24:20 +10:00
$exception = new ApplicationException($proposedException->getMessage(), 0);
$exception->setMask($proposedException);
}
// Ensure System view path is registered
2014-05-14 23:24:20 +10:00
View::addNamespace('system', base_path().'/modules/system/views');
return View::make('system::exception', ['exception' => $exception]);
}
/**
* Prepares a mask exception to be used when any exception fires.
* @param Exception $exception The mask exception.
* @return void
*/
public static function applyMask(\Exception $exception)
{
2014-10-18 11:58:50 +02:00
if (static::$activeMask !== null) {
array_push(static::$maskLayers, static::$activeMask);
2014-10-18 11:58:50 +02:00
}
2014-05-14 23:24:20 +10:00
static::$activeMask = $exception;
}
/**
* Destroys the prepared mask by applyMask()
* @return void
*/
public static function removeMask()
{
2014-10-18 11:58:50 +02:00
if (count(static::$maskLayers) > 0) {
static::$activeMask = array_pop(static::$maskLayers);
}
else {
static::$activeMask = null;
2014-10-18 11:58:50 +02:00
}
2014-05-14 23:24:20 +10:00
}
/**
* Looks up an error page using the CMS route "/error". If the route does not
* exist, this function will use the error view found in the Cms module.
* @return mixed Error page contents.
*/
public function handleCustomError()
{
$theme = Theme::getActiveTheme();
// Use the default view if no "/error" URL is found.
$router = new Router($theme);
2014-10-18 11:58:50 +02:00
if (!$router->findByUrl('/error')) {
2014-05-14 23:24:20 +10:00
return View::make('cms::error');
2014-10-18 11:58:50 +02:00
}
2014-05-14 23:24:20 +10:00
// Route to the CMS error page.
$controller = new Controller($theme);
return $controller->run('/error');
}
2014-10-18 11:58:50 +02:00
}