Search code examples
ruby-on-railserror-handlingruby-on-rails-5actiondispatch

Rails with custom error through routes - read original requested URL


I am using a custom error controller. I would like to have a 200 response code when visiting the 500 page URL (otherwise my middleware that intercepts 500 response codes sends me an exception email whenever I want to show off my 500)

It would seem using the self.routes as exceptions_app will change the request.path to always be equal to the error number

Target

  • visit www.example.com/crashy_url # => Should show custom 500 error template with 500 response code
  • visit www.example.com/500 # => Should show custom 500 error template with 200 response code

Problem

  • visit www.example.com/crashy_url # => request.path is equal to `/500' so my controller sends a 200 response code

How can I extract the really visited URL with this ?

# config/application.rb
config.exceptions_app = self.routes

# routes
match '/500', to: 'errors#server_error', via: :all

# app/controllers/errors_controller.rb
def server_error
    @status = 500
    can_be_visited_with_ok_response_code
    show
  end

def can_be_visited_with_ok_response_code
    # We want to hide hide the faulty status if the user only wanted to see how our beautiful /xxx page looks like
    # BUT `action_dispatch/middleware/debug_exceptions` will change request.path to be equal to the error !!
    # @status = 200 if request.path == "/#{@status}" # BAD request.path will always return response code
  end

  def show
    respond_to do |format|
      format.html { render 'show', status: @status }
      format.all  { head @status }
    end
  end

Solution

  • I love Ruby and did_you_mean... I was able to guess the correct method name: request.original_fullpath should be used instead to get the original URL entered by the user.

    @status = 200 if request.original_fullpath == "/#{@status}"
    

    Note that request.original_url can also give you the full path including the host name