Throw exception and have a Status: 404 Not Found response

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Throw exception and have a Status: 404 Not Found response

Jurian Sluiman
What's the best option to throw an exception in a controller and expect it to result in a Status: 404 Not Found response header?

Previously in old zf1 apps I could throw an ArticleNotFoundException in my blog or a ProductNotFoundException in my webshop. The error handler I had checked some marker interfaces and switched to different http status codes. I would like to do the same now in zf2. What's the best approach?

The error handling seems to be nested pretty deep inside the MVC application now, so I don't know where to start: hook into a specific event, create a special factory for an existing listener: I am not sure.
--
Jurian Sluiman
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Throw exception and have a Status: 404 Not Found response

weierophinney
Administrator
-- Jurian Sluiman <[hidden email]> wrote
(on Sunday, 03 June 2012, 11:35 PM +0200):
> What's the best option to throw an exception in a controller and expect it to
> result in a Status: 404 Not Found response header?

Don't throw an exception. Simply grab the response object, and set a 404
status code on it. Doing so will trigger the RouteNotFoundStrategy and
allow displaying a 404 page. (You can do similarly with a 500 status
code.)

> Previously in old zf1 apps I could throw an ArticleNotFoundException in my blog
> or a ProductNotFoundException in my webshop. The error handler I had checked
> some marker interfaces and switched to different http status codes. I would
> like to do the same now in zf2. What's the best approach?
>
> The error handling seems to be nested pretty deep inside the MVC application
> now, so I don't know where to start: hook into a specific event, create a
> special factory for an existing listener: I am not sure.

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Throw exception and have a Status: 404 Not Found response

Jurian Sluiman
2012/6/5 Matthew Weier O'Phinney <[hidden email]>
-- Jurian Sluiman <[hidden email]> wrote
(on Sunday, 03 June 2012, 11:35 PM +0200):
> What's the best option to throw an exception in a controller and expect it to
> result in a Status: 404 Not Found response header?

Don't throw an exception. Simply grab the response object, and set a 404
status code on it. Doing so will trigger the RouteNotFoundStrategy and
allow displaying a 404 page. (You can do similarly with a 500 status
code.)

 This is what I was looking for. It is not documented (as documentation suggests responses are bubbling up to application level [1]) but I'll look into this, thanks!


--
Jurian Sluiman
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Throw exception and have a Status: 404 Not Found response

Jurian Sluiman
2012/6/5 Jurian Sluiman <[hidden email]>
2012/6/5 Matthew Weier O'Phinney <[hidden email]>
-- Jurian Sluiman <[hidden email]> wrote
(on Sunday, 03 June 2012, 11:35 PM +0200):
> What's the best option to throw an exception in a controller and expect it to
> result in a Status: 404 Not Found response header?

Don't throw an exception. Simply grab the response object, and set a 404
status code on it. Doing so will trigger the RouteNotFoundStrategy and
allow displaying a 404 page. (You can do similarly with a 500 status
code.)

 This is what I was looking for. It is not documented (as documentation suggests responses are bubbling up to application level [1]) but I'll look into this, thanks!


As far as I can see now the process you described is not possible Matthew. I updated zf2 to 88c4b4cc6325209d8eb4f8b8e2d45f459bb5679d and the response I return is immediately sent to the browser. This results in a Status: 404 Not Found header, but obviously in an empty response too.

If I do not return the Response object, but only set its status code and throw an exception afterwards, the status code is corrected to a 500. While your suggested sounds good, its not implemented yet or does not work as expected. Any thoughts on this?
--
Jurian Sluiman
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Throw exception and have a Status: 404 Not Found response

weierophinney
Administrator
-- Jurian Sluiman <[hidden email]> wrote
(on Tuesday, 05 June 2012, 09:46 PM +0200):

> 2012/6/5 Jurian Sluiman <[hidden email]>
>
>     2012/6/5 Matthew Weier O'Phinney <[hidden email]>
>
>         -- Jurian Sluiman <[hidden email]> wrote
>         (on Sunday, 03 June 2012, 11:35 PM +0200):
>         > What's the best option to throw an exception in a controller and
>         expect it to
>         > result in a Status: 404 Not Found response header?
>
>         Don't throw an exception. Simply grab the response object, and set a
>         404
>         status code on it. Doing so will trigger the RouteNotFoundStrategy and
>         allow displaying a 404 page. (You can do similarly with a 500 status
>         code.)
>
>
>      This is what I was looking for. It is not documented (as documentation
>     suggests responses are bubbling up to application level [1]) but I'll look
>     into this, thanks!
>
>     [1] http://packages.zendframework.com/docs/latest/manual/en/
>     zend.mvc.examples.html#
>     zend.mvc.examples.controllers.accessing-the-request-and-response
>
>
> As far as I can see now the process you described is not possible Matthew. I
> updated zf2 to 88c4b4cc6325209d8eb4f8b8e2d45f459bb5679d and the response I
> return is immediately sent to the browser. This results in a Status: 404 Not
> Found header, but obviously in an empty response too.
>
> If I do not return the Response object, but only set its status code and throw
> an exception afterwards, the status code is corrected to a 500. While your
> suggested sounds good, its not implemented yet or does not work as expected.
> Any thoughts on this?

I said set the status code, not return the response. :)

That's really all there is to it -- I've used it recently in stuff I was
working up to demo for DPC, and also use it in a custom PageController
in my website.

Look in Zend\Mvc\View\RouteNotFoundListener and ExceptionListener --
they each check the response status code, and, if so, inject an
appropriate ViewModel into the layout.

If you _return_ the response, the MVC expects that it's complete, and
tries to return it immediately. That's why you should only set the
status code, but not return the response. I've done it simply like this:

    $this->getResponse()->setStatusCode(404);
    return;


--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Throw exception and have a Status: 404 Not Found response

Goran Jurić

On 6. lip. 2012., at 00:11, Matthew Weier O'Phinney wrote:

I said set the status code, not return the response. :)

That's really all there is to it -- I've used it recently in stuff I was
working up to demo for DPC, and also use it in a custom PageController
in my website. 

Look in Zend\Mvc\View\RouteNotFoundListener and ExceptionListener --
they each check the response status code, and, if so, inject an
appropriate ViewModel into the layout. 

If you _return_ the response, the MVC expects that it's complete, and
tries to return it immediately. That's why you should only set the 
status code, but not return the response. I've done it simply like this:

   $this->getResponse()->setStatusCode(404);
   return;

What are the chances of supporting custom exceptions that would produce the
same result? I am not quite up to speed with ZF2 development so I do not have
insight into the inner workings of MVC but it dosn't sound like it should be to 
complicated.

The exception listener could check for specific exceptions and do the same thing
it does when it encounters a 404 status code.

Regards,

Goran Jurić
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Throw exception and have a Status: 404 Not Found response

weierophinney
Administrator
-- Goran Jurić <[hidden email]> wrote
(on Tuesday, 12 June 2012, 04:31 PM +0200):

> On 6. lip. 2012., at 00:11, Matthew Weier O'Phinney wrote:
>
>
>     I said set the status code, not return the response. :)
>
>     That's really all there is to it -- I've used it recently in stuff I was
>     working up to demo for DPC, and also use it in a custom PageController
>     in my website.
>
>     Look in Zend\Mvc\View\RouteNotFoundListener and ExceptionListener --
>     they each check the response status code, and, if so, inject an
>     appropriate ViewModel into the layout.
>
>     If you _return_ the response, the MVC expects that it's complete, and
>     tries to return it immediately. That's why you should only set the
>     status code, but not return the response. I've done it simply like this:
>
>        $this->getResponse()->setStatusCode(404);
>        return;
>
>
> What are the chances of supporting custom exceptions that would produce the
> same result? I am not quite up to speed with ZF2 development so I do not have
> insight into the inner workings of MVC but it dosn't sound like it should be
> to
> complicated.
>
> The exception listener could check for specific exceptions and do the
> same thing it does when it encounters a 404 status code.

You can implement this by attaching a listener to dispatch.error on a
priority > 1. Just examine the exception thrown and then determine what
to do from there -- take a look at the ExceptionListener and/or
RouteNotFoundListener, in the methods that listen on that event.

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Loading...