discourse/lib/middleware/discourse_public_exceptions.rb
Sam Saffron 30990006a9 DEV: enable frozen string literal on all files
This reduces chances of errors where consumers of strings mutate inputs
and reduces memory usage of the app.

Test suite passes now, but there may be some stuff left, so we will run
a few sites on a branch prior to merging
2019-05-13 09:31:32 +08:00

51 lines
1.7 KiB
Ruby

# frozen_string_literal: true
# since all the rescue from clauses are not caught by the application controller for matches
# we need to handle certain exceptions here
module Middleware
class DiscoursePublicExceptions < ::ActionDispatch::PublicExceptions
def initialize(path)
super
end
def call(env)
# this is so so gnarly
# sometimes we leak out exceptions prior to creating a controller instance
# this can happen if we have an exception in a route constraint in some cases
# this code re-dispatches the exception to our application controller so we can
# properly translate the exception to a page
exception = env["action_dispatch.exception"]
response = ActionDispatch::Response.new
# Special handling for invalid params, in this case we can not re-dispatch
# the Request object has a "broken" .params which can not be accessed
exception = nil if Rack::QueryParser::InvalidParameterError === exception
# We also can not dispatch bad requests as no proper params
exception = nil if ActionController::BadRequest === exception
if exception
begin
fake_controller = ApplicationController.new
fake_controller.response = response
fake_controller.request = ActionDispatch::Request.new(env)
if ApplicationController.rescue_with_handler(exception, object: fake_controller)
body = response.body
if String === body
body = [body]
end
return [response.status, response.headers, body]
end
rescue => e
Discourse.warn_exception(e, message: "Failed to handle exception in exception app middleware")
end
end
super
end
end
end