I'm trying to redefine exception handler for a couple of my controllers in Zend (RESTful).
This is my piece of code:
abstract class RestController extends Zend_Rest_Controller
{
public function init()
{
set_exception_handler(array($this, 'fault'));
}
public function fault($exception = null, $code = null)
{
echo $exception->getMessage();
}
}
But for some reason Zend uses default template/error handling and my fault
function didnt execute.
Btw, I'm using module
architecture. that controller is from rest
module.. Zend's default error handler is from default
module.
This is an interesting question. I'm not totally sure at the moment so I'm going to research this one a bit and see what I come up with. For now there are workarounds that aren't too ghetto either. One way would be to create an abstract controller from which to extend all of your controllers in your rest module.
abstract class RestAbstractController extends Zend_Rest_Controller
{
final public function __call($methodName, $args)
{
throw new MyRestException("Method {$methodName} doesn't exist", 500);
}
}
// the extends part here is optional
class MyRestException extends Zend_Rest_Exception
{
public function fault($exception = null, $code = null)
{
echo $exception->getMessage() . ' ' . __CLASS__;
exit;
}
}
class RestController extends RestAbstractController
{
// method list
}
Also, I found this interesting article: http://zend-framework-community.634137.n4.nabble.com/Dealing-with-uncatched-exceptions-and-using-set-exception-handler-in-Zend-Framework-td1566606.html
Edit:
Somewhere in your bootstrap file you will need to add this:
$this->_front->throwExceptions(true);
$ex = new MyRestException();
set_exception_handler(array($ex, 'fault'));
The first line there should effectively turn off Zend's exception handling, the only thing missing is a control structure to determine if the current request is for your REST service or not. NOTE The reason this had to go in the Bootstrap.php file was that your call to set_exception_handler() in the init() function was never reached because Zend Framework threw the exception first. Placing that in the bootstrap file will counter that.
Finally solved the problem by myself :)
From Zend documentation:
Zend_Controller_Front::throwExceptions()
By passing a boolean TRUE value to this method, you can tell the front
controller that instead of aggregating exceptions in the response
object or using the error handler plugin, you'd rather handle them
yourself
So, correct solution is this:
abstract class RestController extends Zend_Rest_Controller
{
public function init()
{
$front = Zend_Controller_Front::getInstance();
$front->throwExceptions(true);
set_exception_handler(array($this, 'fault'));
}
public function fault($exception = null, $code = null)
{
echo $exception->getMessage();
}
}
We just have to add
$front = Zend_Controller_Front::getInstance();
$front->throwExceptions(true);
before set_exception_handler
to make it work.