diff --git a/lib/Cake/Error/ExceptionRenderer.php b/lib/Cake/Error/ExceptionRenderer.php index 60482db10..338a98253 100644 --- a/lib/Cake/Error/ExceptionRenderer.php +++ b/lib/Cake/Error/ExceptionRenderer.php @@ -285,6 +285,12 @@ class ExceptionRenderer { } else { $this->_outputMessage('error500'); } + } catch (MissingPluginException $e) { + $attributes = $e->getAttributes(); + if (isset($attributes['plugin']) && $attributes['plugin'] === $this->controller->plugin) { + $this->controller->plugin = null; + } + $this->_outputMessageSafe('error500'); } catch (Exception $e) { $this->_outputMessageSafe('error500'); } diff --git a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php index d24bbb55c..51cc4ef70 100644 --- a/lib/Cake/Test/Case/Error/ExceptionRendererTest.php +++ b/lib/Cake/Test/Case/Error/ExceptionRendererTest.php @@ -764,6 +764,73 @@ class ExceptionRendererTest extends CakeTestCase { $this->assertEquals('Errors', $ExceptionRenderer->controller->viewPath); } +/** + * Test that missing plugin disables Controller::$plugin if the two are the same plugin. + * + * @return void + */ + public function testMissingPluginRenderSafe() { + $exception = new NotFoundException(); + $ExceptionRenderer = new ExceptionRenderer($exception); + + $ExceptionRenderer->controller = $this->getMock('Controller', array('render')); + $ExceptionRenderer->controller->plugin = 'TestPlugin'; + $ExceptionRenderer->controller->request = $this->getMock('CakeRequest'); + + $exception = new MissingPluginException(array('plugin' => 'TestPlugin')); + $ExceptionRenderer->controller->expects($this->once()) + ->method('render') + ->with('error400') + ->will($this->throwException($exception)); + + $response = $this->getMock('CakeResponse'); + $response->expects($this->once()) + ->method('body') + ->with($this->logicalAnd( + $this->logicalNot($this->stringContains('test plugin error500')), + $this->stringContains('Not Found') + )); + + $ExceptionRenderer->controller->response = $response; + $ExceptionRenderer->render(); + } + +/** + * Test that missing plugin doesn't disable Controller::$plugin if the two aren't the same plugin. + * + * @return void + */ + public function testMissingPluginRenderSafeWithPlugin() { + App::build(array( + 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS) + ), App::RESET); + CakePlugin::load('TestPlugin'); + $exception = new NotFoundException(); + $ExceptionRenderer = new ExceptionRenderer($exception); + + $ExceptionRenderer->controller = $this->getMock('Controller', array('render')); + $ExceptionRenderer->controller->plugin = 'TestPlugin'; + $ExceptionRenderer->controller->request = $this->getMock('CakeRequest'); + + $exception = new MissingPluginException(array('plugin' => 'TestPluginTwo')); + $ExceptionRenderer->controller->expects($this->once()) + ->method('render') + ->with('error400') + ->will($this->throwException($exception)); + + $response = $this->getMock('CakeResponse'); + $response->expects($this->once()) + ->method('body') + ->with($this->logicalAnd( + $this->stringContains('test plugin error500'), + $this->stringContains('Not Found') + )); + + $ExceptionRenderer->controller->response = $response; + $ExceptionRenderer->render(); + CakePlugin::unload(); + } + /** * Test that exceptions can be rendered when an request hasn't been registered * with Router diff --git a/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Errors/error500.ctp b/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Errors/error500.ctp new file mode 100644 index 000000000..cd0fd5995 --- /dev/null +++ b/lib/Cake/Test/test_app/Plugin/TestPlugin/View/Errors/error500.ctp @@ -0,0 +1,11 @@ +test plugin error500 +
++ : + +
+ 0): + echo $this->element('exception_stack_trace'); +endif; +?>