Skip to content

Commit 6038a2d

Browse files
committed
Properly handle routing errors
Routing errors are converted into generic 404 responses then sent up the middleware stack as a normal response. One thing to note is that they include a special `X-Cascade` error. Supposedly, [this header](http://stackoverflow.com/a/5644114/47438) is meant to indicate that other middleware can inspect and try to handle the route. This allows gems like `devise` to have default routes for sign in and sign up configured, but still lets the application create custom routes if it wants. Since this is our error handler, it is the place to stop the chain and raise an appropriate routing error. We could simply toggle on the header and call our `render_json_error` in the `if` block, but by using the error it hooks directly into our existing logic - no need to duplicate it. It also means we can register the routing error with our public exceptions or standard error handler without worrying about special edge cases. Finally, by raising an error it properly represents the fact that this was a routing error. BTW this is the strategy that Rails itself uses.
1 parent 9e1cc70 commit 6038a2d

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

lib/kracken/json_api/public_exceptions.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,20 @@ def call(env)
1414
end
1515
end
1616

17+
# Use similar logic to how `ActionDispatch::DebugExceptions` captures
18+
# routing errors.
19+
# https://github.com/rails/rails/blob/v4.2.6/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
1720
def capture_error(env)
18-
@app.call(env)
21+
_, headers, body = response = @app.call(env)
22+
23+
if headers['X-Cascade'] == 'pass'
24+
body.close if body.respond_to?(:close)
25+
raise ActionController::RoutingError,
26+
"No route matches [#{env['REQUEST_METHOD']}] " \
27+
"#{env['PATH_INFO'].inspect}"
28+
end
29+
30+
response
1931
rescue Exception => exception
2032
render_json_error(ExceptionWrapper.new(env, exception))
2133
end

0 commit comments

Comments
 (0)