Skip to content

Commit

Permalink
Route unknown error to parent exception's handler
Browse files Browse the repository at this point in the history
  • Loading branch information
syeopite committed Sep 20, 2024
1 parent 9c64861 commit e7f441a
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions src/kemal/exception_handler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,38 @@ module Kemal
rescue ex : Exception
# Use error handler defined for the current exception if it exists
return call_exception_with_exception(context, ex, 500) if Kemal.config.error_handlers.has_key?(ex.class)

# Use error handler for an ancestor of the current exception if it exists
Kemal.config.error_handlers.each_key do |key|
if key.is_a? Exception.class && ex.class <= key
return call_exception_with_exception(context, ex, 500, override_handler_used: key)
end
end

log("Exception: #{ex.inspect_with_backtrace}")
# Else use generic 500 handler if defined
return call_exception_with_status_code(context, ex, 500) if Kemal.config.error_handlers.has_key?(500)
verbosity = Kemal.config.env == "production" ? false : true
render_500(context, ex, verbosity)
end

private def call_exception_with_exception(context : HTTP::Server::Context, exception : Exception, status_code : Int32 = 500)
# Calls the defined error handler for the given exception if it exists
#
# By default it tries to use the handler that is defined for the given exception. However, another
# handler can be used via the `override_handler_used` parameter.
private def call_exception_with_exception(context : HTTP::Server::Context, exception : Exception, status_code : Int32 = 500, override_handler_used : (Exception.class)? = nil)
return if context.response.closed?

if !Kemal.config.error_handlers.empty? && Kemal.config.error_handlers.has_key?(exception.class)
if !override_handler_used
handler_to_use = exception.class
else
handler_to_use = override_handler_used
end

if !Kemal.config.error_handlers.empty? && Kemal.config.error_handlers.has_key?(handler_to_use)
context.response.content_type = "text/html" unless context.response.headers.has_key?("Content-Type")
context.response.status_code = status_code
context.response.print Kemal.config.error_handlers[exception.class].call(context, exception)
context.response.print Kemal.config.error_handlers[handler_to_use].call(context, exception)
context
end
end
Expand Down

0 comments on commit e7f441a

Please sign in to comment.