During Zend_Controller_Action::init()
, is there a way to cancel the action (so it won't be called)?
<?php
class JsonApiController extends Zend_Controller_Action {
function init()
{
// try JSON decoding the raw request body
if ($jsonDecodingFailed) {
echo '{"error":"invalid JSON"}';
$this->_cancelAction(); // something like this exist?
}
}
}
My current workaround is to make an empty nullAction()
method and call $this->_forward('null')
to forward to it.
Theres nothing wrong in using $this->_forward() inside the init() (if the method you want to forward to is inside the same controller as the init()), this will simply change the request object's controller / action (overwrite what has been set via the router).
An alternative to this would be to create a Zend_Controller_Plugin as it looks like you are handling unexpected errors. Have a look at the Zend_Controller_Plugin_ErrorHandler implementation. So instead of forwarding to another action you would throw an exception, and have your custom plugin check in postDispatch() if the response contains eny expections, and if it does simply edit the current Request object to show your "cancel" action.
$request->setDispatched(false)
->setControllerName("error")
->setActionName("jsonDecoding");
The last way could be to just throw a exit after the echo "{error: "invalid json"}" not very nice but you will avoid the overload of having another dispatch iteration.
I would throw an exception (and then catch it in error controller) - that's what you do when there is non-recoverable error.
Maybe try this:
$this->_helper->viewRenderer->setNoRender();
return;
For someone that is still looking for solution you can try this:
Add a flag stating whether there is an error or not and override dispatch method. If the flag is set, do not invoke parent::dispatch
.
This works the way I want it to. My reason was that I am making an abstract API controller, which by default checks for an API key in request, if its not there - controller should respond with error and complete request successfully.
E.g.
abstract class Api_Controller extends Zend_Rest_Controller{
private $responded = false;
public function init() {
parent::init();
if(!$this->isKeyValid())
$this->respond("invalid key"); // this would set flag to true and handle error
}
public function dispatch($action) {
// if an error occured and it was dispatched, do not call action method, just finish request
if(!$this->responded)
parent::dispatch($action);
}
}
For me this seems like a clean solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With