0

In my Rails 7 API only mode, I'm trying to catch case when someone is trying to make a request into api/v1/mandate instead of api/v1/mandates (classic ActionController::RoutingError case). In such case it will render the 404 error with some build in stuff as JSON response. I want to customize that JSON error answer inside my BaseController. I was trying:

#base_controller.rb
module Api
  module V1
    class BaseController < ActionController::API
      rescue_from ActionController::RoutingError, with: :render_not_found_error

      private

      def render_not_found_error(exception)
        render json: { error: true, message: exception.message }, status: :not_found
      end
    end
  end
end

I've also have:

#config/environments/development.rb
config.consider_all_requests_local = true

But nothing changed, still doesn't get my JSON error.

mr_muscle
  • 2,536
  • 18
  • 61
  • Sorry for the lameness of using a question I have answered as a dupe target. It was the best one I could find. – max Dec 26 '22 at 19:21

1 Answers1

1

You can't rescue routing errors in a controller because the exceptions occur in the routing layer, not the controller.

For missing routes, you need a "catch-all" route that can capture them and then forward that to a controller which performs your "exception" handling.

In practice this often shakes out as a NotFoundController with different actions depending on the type of route being handled.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • I know I could do something like this https://web-crunch.com/posts/custom-error-page-ruby-on-rails but that won't work in API only mode because of routing I guess (there is no /404 page in API I guess). Any sample of code how to handle? – mr_muscle Dec 23 '22 at 14:40
  • 1
    You add a second route like `/api/v1/*` that catches this, making sure to put that last so it has the lowest precedence. You can even do `/api/:ver/*path` to catch all kinds of issues. – tadman Dec 23 '22 at 15:00
  • 1
    @mr_muscle I run multiple rails backed APIs and all of them have a root catch all just `match '*path'` that redirects to a standard handler and simply responds with a JSON error that the path doesn't exist. – engineersmnky Dec 23 '22 at 16:19