tags:

views:

99

answers:

1

Is it possible to have the router return an error code (or an entire rack response) in response to a matched route?

E.g. I have move from WordPress to a home grown blogging solution. Search engines are hitting URLs like '/?tag=ruby' that need to return a 406 error. Instead, the router dutifully routes them to the same place as '/' I can match the URLs I want to get rid of but I don't know what to do with them

A: 

This is not obvious, but it is effective.

Solution:

match('/',:query_string=>/.+/).defer_to do |request, params|
  raise Merb::ControllerExceptions::NotAcceptable, 
        "Query String Unknown: #{request.query_string}"
end

Explanation:

In order to trigger a 406 error we need to raise Merb::ControllerExceptions::NotAcceptable but if we do this while setting up the routes it helps exactly no one. Instead we need to wait until Merb is handling the request. this is what the defer_to block does. When the request comes in we raise the error and it is caught and handled just as it would be if we through this error from a controller.

Problems

One of the goals of my original question was to avoid having to go through all of the dispatching overhead. Instead this solution is dispatched through the exceptions controller which more computationally expensive then [406,{'content-type'=>'text/plain},['406 Not Acceptable']]

John F. Miller