I have the following route:
Rails.application.routes.draw do
get '/:id', to: 'foo#bar', constraints: { id: /\d+/ }
end
/1 loads my record with id #1. The problem is that my route conflicts with Rails default static pages (404, 500, etc ...).
How can I have static error pages with my dynamic routes working?
If it's possible, I don't mind moving my static pages to a route like /errors/404, for example.
EDIT 1:
Reopening ActionDispatch::ShowExceptions class and changing the private method render_exception is a extremely hacky solution:
config/application.rb:
require_relative 'boot'
require 'rails/all'
Bundler.require(*Rails.groups)
module MyApp
class Application < Rails::Application
config.load_defaults 5.2
config.exceptions_app = self.routes
end
end
module ActionDispatch
class ShowExceptions
private
def render_exception(request, exception)
backtrace_cleaner = request.get_header "action_dispatch.backtrace_cleaner"
wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)
status = wrapper.status_code
request.set_header "action_dispatch.exception", wrapper.exception
request.set_header "action_dispatch.original_path", request.path_info
request.path_info = "/errors/#{status}"
response = @exceptions_app.call(request.env)
response[1]["X-Cascade"] == "pass" ? pass_response(status) : response
rescue Exception => failsafe_error
$stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}"
FAILSAFE_RESPONSE
end
end
end
I've changed request.path_info = "/#{status}"
to request.path_info = "/errors/#{status}"
.
I don't like this solution at all.
You can change the directory that renders exceptions. You will need to change some configuration, so for example you could put the following in config/application.rb
within your Application
class:
config.exceptions_app = ActionDispatch::PublicExceptions.new(Rails.public_path.join('errors'))
Then move those static 404.html
and 500.html
from public
to a newly created public/errors
dir.