Skip to content

Commit

Permalink
Fix errors with missing sub directories.
Browse files Browse the repository at this point in the history
Missing content-type specific errors shouldn't trigger fatal errors.
Instead a html view should be rendered as a last resort.

Fixes #2537
  • Loading branch information
markstory committed Feb 3, 2012
1 parent 62df929 commit ee083e0
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 18 deletions.
1 change: 0 additions & 1 deletion lib/Cake/Controller/CakeErrorController.php
Expand Up @@ -57,7 +57,6 @@ public function __construct($request = null, $response = null) {
$this->Components->trigger('initialize', array(&$this));

$this->_set(array('cacheAction' => false, 'viewPath' => 'Errors'));

if (isset($this->RequestHandler)) {
$this->RequestHandler->startup($this);
}
Expand Down
30 changes: 14 additions & 16 deletions lib/Cake/Error/ExceptionRenderer.php
Expand Up @@ -183,14 +183,8 @@ protected function _cakeError(CakeException $error) {
'error' => $error,
'serialize' => array('code', 'url', 'name')
));
try {
$this->controller->set($error->getAttributes());
$this->_outputMessage($this->template);
} catch (MissingViewException $e) {
$this->_outputMessage('error500');
} catch (Exception $e) {
$this->_outputMessageSafe('error500');
}
$this->controller->set($error->getAttributes());
$this->_outputMessage($this->template);
}

/**
Expand Down Expand Up @@ -255,11 +249,7 @@ public function pdoError(PDOException $error) {
'error' => $error,
'serialize' => array('code', 'url', 'name', 'error')
));
try {
$this->_outputMessage($this->template);
} catch (Exception $e) {
$this->_outputMessageSafe('error500');
}
$this->_outputMessage($this->template);
}

/**
Expand All @@ -269,9 +259,13 @@ public function pdoError(PDOException $error) {
* @return void
*/
protected function _outputMessage($template) {
$this->controller->render($template);
$this->controller->afterFilter();
$this->controller->response->send();
try {
$this->controller->render($template);
$this->controller->afterFilter();
$this->controller->response->send();
} catch (Exception $e) {
$this->_outputMessageSafe('error500');
}
}

/**
Expand All @@ -282,8 +276,12 @@ protected function _outputMessage($template) {
* @return void
*/
protected function _outputMessageSafe($template) {
$this->controller->layoutPath = '';
$this->controller->subDir = '';
$this->controller->helpers = array('Form', 'Html', 'Session');
$this->controller->viewClass = 'View';
$this->controller->render($template);
$this->controller->response->type('html');
$this->controller->response->send();
}
}
39 changes: 38 additions & 1 deletion lib/Cake/Test/Case/Error/ExceptionRendererTest.php
Expand Up @@ -640,7 +640,7 @@ public function testMissingRenderSafe() {
->with('missingHelper')
->will($this->throwException($exception));

$ExceptionRenderer->controller->expects($this->at(3))
$ExceptionRenderer->controller->expects($this->at(4))
->method('render')
->with('error500')
->will($this->returnValue(true));
Expand All @@ -651,6 +651,43 @@ public function testMissingRenderSafe() {
$this->assertEquals(array('Form', 'Html', 'Session'), $ExceptionRenderer->controller->helpers);
}

/**
* Test that missing subDir/layoutPath don't cause other fatal errors.
*
* @return void
*/
public function testMissingSubdirRenderSafe() {
$exception = new NotFoundException();
$ExceptionRenderer = new ExceptionRenderer($exception);

$ExceptionRenderer->controller = $this->getMock('Controller');
$ExceptionRenderer->controller->helpers = array('Fail', 'Boom');
$ExceptionRenderer->controller->layoutPath = 'json';
$ExceptionRenderer->controller->subDir = 'json';
$ExceptionRenderer->controller->viewClass = 'Json';
$ExceptionRenderer->controller->request = $this->getMock('CakeRequest');

$ExceptionRenderer->controller->expects($this->at(1))
->method('render')
->with('error400')
->will($this->throwException($exception));

$ExceptionRenderer->controller->expects($this->at(3))
->method('render')
->with('error500')
->will($this->returnValue(true));

$ExceptionRenderer->controller->response = $this->getMock('CakeResponse');
$ExceptionRenderer->controller->response->expects($this->once())
->method('type')
->with('html');

$ExceptionRenderer->render();
$this->assertEquals('', $ExceptionRenderer->controller->layoutPath);
$this->assertEquals('', $ExceptionRenderer->controller->subDir);
$this->assertEquals('View', $ExceptionRenderer->controller->viewClass);
}

/**
* Test that exceptions can be rendered when an request hasn't been registered
* with Router
Expand Down

0 comments on commit ee083e0

Please sign in to comment.