Exception handling and catch-all routes?

124 views
Skip to first unread message

Keith Irwin

unread,
Oct 20, 2011, 4:31:50 PM10/20/11
to clj-...@googlegroups.com
Hi! Brand new to web noir. Seems really nice.

However, a couple of questions before I even get to writing something fun in it:

1. Are there standard "catch-all" routes such as a not-found handler, or an error handler (with a reference to an exception that gets thrown) and so on?

I figure I can just use a post-route, but how to I get a reference to an exception thrown in a handler somewhere?

2. noir.exception seems to be exactly what I want, but the documentation is empty!

I'll look at the source presently, but thought you should know, in case there's an error with the documentation generator.

Regards,
Keith

Mark Rathwell

unread,
Oct 20, 2011, 5:07:14 PM10/20/11
to clj-...@googlegroups.com
Hi,

1. There are status handlers for 404 and 500 setup by default. To
create your own custom status page, use:

(noir.statuses/set-page! code content)

before starting the server.

2. As for getting the exception, Noir includes a middleware function
called wrap-exceptions that will print the stack trace if in :dev
mode, and will return the 500 status page if not. To actually get the
exception and do stuff with it yourself, you would probably want to
write a similar middleware that will store the exception somewhere you
can get to it (in a dynamic thread-local var, for example).

- Mark

Mark Rathwell

unread,
Oct 20, 2011, 5:20:49 PM10/20/11
to clj-...@googlegroups.com
> 2. As for getting the exception, Noir includes a middleware function
> called wrap-exceptions that will print the stack trace if in :dev
> mode, and will return the 500 status page if not.  To actually get the
> exception and do stuff with it yourself, you would probably want to
> write a similar middleware that will store the exception somewhere you
> can get to it (in a dynamic thread-local var, for example).

Actually, it might make more sense if Noir bound the exception in
wrap-exceptions to something like, for example, noir.exception/*excp*.
Is this something that would be considered?

Keith Irwin

unread,
Oct 20, 2011, 5:22:23 PM10/20/11
to clj-...@googlegroups.com
Thanks! After some digging around, that makes sense.

How about setting custom headers? Does that have to be done in a middleware handler, too? I have some specialized tasks outside the normal web-app stuff for which I'd like to add some headers on the response, but don't see how to do that.

Even returning {:status 200 :headers {:test "Test"}} gets me a "Key must be integer" error, which is completely opaque to me at this point.

I realize that such things are a little bit low level, but I just need it for this one part..... ;)

Keith

Keith Irwin

unread,
Oct 20, 2011, 5:26:18 PM10/20/11
to clj-...@googlegroups.com
Actually, never mind. I was trying to return a header in a pre-route handler. I'm not sure how to make a pre-route handler return a response under some conditions short-circuiting the rest of the pages. Probable really need middleware.

Keith

Mark Rathwell

unread,
Oct 20, 2011, 5:30:23 PM10/20/11
to clj-...@googlegroups.com

You can redirect to another page from the pre-route. That should work
for most situations.

(require '[noir.response :as response]
...
(pre-route "/some/path" {}
(if some-condition
(response/redirect "/some/other/path")))

Chris Granger

unread,
Oct 21, 2011, 2:05:21 PM10/21/11
to clj-...@googlegroups.com
What would you do with a bound exception? The exception would stop the handler's execution, so it's not like you could really do anything with it. You'd need to write middleware anyways. Is there a case I'm missing?

Keith, In terms of the pre-route returning a map with headers, that should definitely work. Can you put up a gist of the exact code you were using?

Cheers,
Chris.

Mark Rathwell

unread,
Oct 21, 2011, 2:29:25 PM10/21/11
to clj-...@googlegroups.com
> The exception would stop the handler's execution, so it's not like you could really do anything with it.

Yeah, I completely missed that fact. I was thinking things like
custom logging and alerts, etc. How would you handle things like
those? I assume by writing your own version of wrap-exceptions, but
then wouldn't be able to use noir.server.handler/wrap-noir-middleware,
correct (so you would need to add the rest of those middlewares
yourself)? I'm wondering if there is a more straightforward way one
could specify a custom exception handler.

- Mark

Chris Granger

unread,
Oct 21, 2011, 2:55:38 PM10/21/11
to clj-...@googlegroups.com
Just catch the exception and don't re-throw it :) By design, custom middleware will intercept before noir's exception handling will. For example, I have one that logs exceptions to a database and then re-throws to get the normal 500 behavior. So you shouldn't have to duplicate what's there, just write something that does whatever other logging you want. Alternatively, you can skip noir's default behavior by catching the exception and not throwing it again. 

Cheers,
Chris.

Mark Rathwell

unread,
Oct 21, 2011, 2:59:18 PM10/21/11
to clj-...@googlegroups.com
Great, thanks! Closed the issue.
Reply all
Reply to author
Forward
0 new messages