Rails 4 adds an exception ActionDispatch::ParamsParser::ParseError exception but since its in the middleware stack it appears it can't be rescued in the normal controller environment. In a json API application I want respond with a standard error format.
This gist shows a strategy for inserting middleware to intercept and respond. Following this pattern I have:
application.rb:
module Traphos
class Application < Rails::Application
....
config.middleware.insert_before ActionDispatch::ParamsParser, "JSONParseError"
end
end
And the middleware is:
class JSONParseError
def initialize(app)
@app = app
end
def call(env)
begin
@app.call(env)
rescue ActionDispatch::ParamsParser::ParseError => e
[422, {}, ['Parse Error']]
end
end
end
If I run my test without the middleware I get (spec):
Failures:
1) Photo update attributes with non-parseable json
Failure/Error: patch update_url, {:description => description}, "CONTENT_TYPE" => content_type, "HTTP_ACCEPT" => accepts, "HTTP_AUTHORIZATION" => @auth
ActionDispatch::ParamsParser::ParseError:
399: unexpected token at 'description=Test+New+Description]'
Which is exactly what I would expect (ParseError that I can't rescue_from).
Now with the only change to add in the middleware above:
2) Photo update attributes with non-parseable json
Failure/Error: response.status.should eql(422)
expected: 422
got: 200
And the log shows that the standard controller action is being executed and returning a normal response (although since it didn't receive any parameters it didn't update anything).
My questions:
How can rescue from ParseError and return a custom response. Feels like I'm on the right track but not quite there.
I can't work out why, when the exception is raised and rescued, that the controller action still proceeds.
Help much appreciated, --Kip