By specifying cascade false
you're saying Grape should be allowed to handle HTTP errors without interference from Rails. Consequently, when an unmatched URI beneath your API's mount point is requested, no ActionController::RoutingError
is generated (this would have been done by Rails) and instead the output from Grape's default "unmatched route" handler is returned verbatim. Somewhat unhelpfully, this handler generates a plain "Not Found" message even when format :json
has been specified, and that is the behaviour you're seeing.
The solution is to provide your own matchers to catch routes other than those specified in your V1
and V2
modules. Try adding this code to API::Base
beneath the three mount
statements:
# Generate a properly formatted 404 error for all unmatched routes except '/'
route :any, '*path' do
error!({ error: 'Not Found',
detail: "No such route '#{request.path}'",
status: '404' },
404)
end
# Generate a properly formatted 404 error for '/'
route :any do
error!({ error: 'Not Found',
detail: "No such route '#{request.path}'",
status: '404' },
404)
end
Naturally you'll want to edit the body of each route
block to suit your needs.
For some reason both blocks seem to be necessary to catch all unmatched routes; this is a limitation of either Grape's matcher syntax or my understanding.