Browse Source

Helpers in custom CakeErrorController are lost

Since many exceptions do not have its own 'template' file, customized
APP/Controller/CakeErrorController with its own list of helpers could be
ignored.

This happens becase ExceptionRenderer is forced to to use _outputMessageSafe
when a template is missing.  This causes Controller::$helpers to be reset with
default values.
Rachman Chavik 13 years ago
parent
commit
07d9a75fcb

+ 6 - 0
lib/Cake/Error/ExceptionRenderer.php

@@ -263,6 +263,12 @@ class ExceptionRenderer {
 			$this->controller->render($template);
 			$this->controller->afterFilter();
 			$this->controller->response->send();
+		} catch (MissingViewException $e) {
+			try {
+				$this->_outputMessage('error500');
+			} catch (Exception $e) {
+				$this->_outputMessageSafe('error500');
+			}
 		} catch (Exception $e) {
 			$this->_outputMessageSafe('error500');
 		}

+ 43 - 0
lib/Cake/Test/Case/Error/ExceptionRendererTest.php

@@ -278,6 +278,49 @@ class ExceptionRendererTest extends CakeTestCase {
 	}
 
 /**
+ * test that helpers in custom CakeErrorController are not lost
+ */
+	public function testCakeErrorHelpersNotLost() {
+		$testApp = CAKE . 'Test' . DS . 'test_app' . DS;
+		App::build(array(
+			'Controller' => array(
+				$testApp . 'Controller' . DS
+			),
+			'View/Helper' => array(
+				$testApp . 'View' . DS . 'Helper' . DS
+			),
+			'View/Layouts' => array(
+				$testApp . 'View' . DS . 'Layouts' . DS
+			),
+			'Error' => array(
+				$testApp . 'Error' . DS
+			),
+		), App::RESET);
+		Configure::write('Error', array(
+			'handler' => 'TestAppsErrorHandler::handleError',
+			'level' => E_ALL & ~E_DEPRECATED,
+			'trace' => true
+		));
+
+		Configure::write('Exception', array(
+			'handler' => 'TestAppsErrorHandler::handleException',
+			'renderer' => 'TestAppsExceptionRenderer',
+			'log' => true
+		));
+
+		App::uses('TestAppsErrorController', 'Controller');
+		App::uses('TestAppsExceptionRenderer', 'Error');
+
+		$exception = new SocketException('socket exception');
+		$renderer = new TestAppsExceptionRenderer($exception);
+
+		ob_start();
+		$renderer->render();
+		$result = ob_get_clean();
+		$this->assertContains('<b>peeled</b>', $result);
+	}
+
+/**
  * test that unknown exception types with valid status codes are treated correctly.
  *
  * @return void

+ 14 - 0
lib/Cake/Test/test_app/Controller/TestAppsErrorController.php

@@ -0,0 +1,14 @@
+<?php
+
+App::uses('CakeErrorController', 'Controller');
+
+class TestAppsErrorController extends CakeErrorController {
+
+	public $helpers = array(
+		'Html',
+		'Session',
+		'Form',
+		'Banana',
+	);
+
+}

+ 21 - 0
lib/Cake/Test/test_app/Error/TestAppsExceptionRenderer.php

@@ -0,0 +1,21 @@
+<?php
+
+class TestAppsExceptionRenderer extends ExceptionRenderer {
+
+	protected function _getController($exception) {
+		App::uses('TestAppsErrorController', 'Controller');
+		if (!$request = Router::getRequest(true)) {
+			$request = new CakeRequest();
+		}
+		$response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
+		try {
+			$controller = new TestAppsErrorController($request, $response);
+			$controller->layout = 'banana';
+		} catch (Exception $e) {
+			$controller = new Controller($request, $response);
+			$controller->viewPath = 'Errors';
+		}
+		return $controller;
+	}
+
+}

+ 5 - 0
lib/Cake/Test/test_app/View/Helper/BananaHelper.php

@@ -19,4 +19,9 @@
 App::uses('Helper', 'View');
 
 class BananaHelper extends Helper {
+
+	public function peel() {
+		return '<b>peeled</b>';
+	}
+
 }

+ 5 - 0
lib/Cake/Test/test_app/View/Layouts/banana.ctp

@@ -0,0 +1,5 @@
+<body>
+<?php
+	echo $this->Banana->peel();
+?>
+</body>