mirror of
https://gitea.invidious.io/iv-org/shard-kemal.git
synced 2024-08-15 00:53:36 +00:00
Merge pull request #92 from jmoriau/decouple-error-hanlder
decoupled errors from route-handler
This commit is contained in:
commit
9ae01c68e9
6 changed files with 61 additions and 30 deletions
|
@ -108,13 +108,14 @@ describe "Kemal::RouteHandler" do
|
||||||
client_response.body.should eq("Skills ruby,crystal")
|
client_response.body.should eq("Skills ruby,crystal")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "renders 404 on not found" do
|
# Removed until there is a way to test multiple middlewares
|
||||||
kemal = Kemal::RouteHandler.new
|
#it "renders 404 on not found" do
|
||||||
request = HTTP::Request.new("GET", "/?message=world")
|
# kemal = Kemal::RouteHandler.new
|
||||||
io_with_context = create_request_and_return_io(kemal, request)
|
# request = HTTP::Request.new("GET", "/?message=world")
|
||||||
client_response = HTTP::Client::Response.from_io(io_with_context, decompress: false)
|
# io_with_context = create_request_and_return_io(kemal, request)
|
||||||
client_response.status_code.should eq 404
|
# client_response = HTTP::Client::Response.from_io(io_with_context, decompress: false)
|
||||||
end
|
# client_response.status_code.should eq 404
|
||||||
|
#end
|
||||||
|
|
||||||
# it "renders 500 on exception" do
|
# it "renders 500 on exception" do
|
||||||
# kemal = Kemal::RouteHandler.new
|
# kemal = Kemal::RouteHandler.new
|
||||||
|
@ -188,13 +189,14 @@ describe "Kemal::RouteHandler" do
|
||||||
client_response.status_code.should eq(200)
|
client_response.status_code.should eq(200)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can't process HTTP HEAD requests for undefined GET routes" do
|
# Removed until there is a way to test multiple middlewares
|
||||||
kemal = Kemal::RouteHandler.new
|
#it "can't process HTTP HEAD requests for undefined GET routes" do
|
||||||
request = HTTP::Request.new("HEAD", "/")
|
# kemal = Kemal::RouteHandler.new
|
||||||
io_with_context = create_request_and_return_io(kemal, request)
|
# request = HTTP::Request.new("HEAD", "/")
|
||||||
client_response = HTTP::Client::Response.from_io(io_with_context, decompress: false)
|
# io_with_context = create_request_and_return_io(kemal, request)
|
||||||
client_response.status_code.should eq(404)
|
# client_response = HTTP::Client::Response.from_io(io_with_context, decompress: false)
|
||||||
end
|
# client_response.status_code.should eq(404)
|
||||||
|
#end
|
||||||
|
|
||||||
it "redirects user to provided url" do
|
it "redirects user to provided url" do
|
||||||
kemal = Kemal::RouteHandler.new
|
kemal = Kemal::RouteHandler.new
|
||||||
|
|
|
@ -7,6 +7,7 @@ at_exit do
|
||||||
config.setup_logging
|
config.setup_logging
|
||||||
config.logger.write "[#{config.env}] Kemal is ready to lead at #{config.scheme}://#{config.host_binding}:#{config.port}\n"
|
config.logger.write "[#{config.env}] Kemal is ready to lead at #{config.scheme}://#{config.host_binding}:#{config.port}\n"
|
||||||
config.add_handler Kemal::StaticFileHandler.new(config.public_folder)
|
config.add_handler Kemal::StaticFileHandler.new(config.public_folder)
|
||||||
|
config.setup_error_handler
|
||||||
config.add_handler Kemal::RouteHandler::INSTANCE
|
config.add_handler Kemal::RouteHandler::INSTANCE
|
||||||
|
|
||||||
server = HTTP::Server.new(config.host_binding.not_nil!.to_slice, config.port, config.handlers)
|
server = HTTP::Server.new(config.host_binding.not_nil!.to_slice, config.port, config.handlers)
|
||||||
|
|
16
src/kemal/common_error_handler.cr
Normal file
16
src/kemal/common_error_handler.cr
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
class Kemal::CommonErrorHandler < HTTP::Handler
|
||||||
|
INSTANCE = new
|
||||||
|
|
||||||
|
def call(context)
|
||||||
|
begin
|
||||||
|
call_next context
|
||||||
|
rescue ex : Kemal::Exceptions::RouteNotFound
|
||||||
|
Kemal.config.logger.write("Exception: #{ex.to_s}: #{ex.message}\n")
|
||||||
|
return render_404(context)
|
||||||
|
rescue ex
|
||||||
|
Kemal.config.logger.write("Exception: #{ex.to_s}: #{ex.message}\n")
|
||||||
|
return render_500(context, ex.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -2,7 +2,7 @@ module Kemal
|
||||||
class Config
|
class Config
|
||||||
INSTANCE = Config.new
|
INSTANCE = Config.new
|
||||||
HANDLERS = [] of HTTP::Handler
|
HANDLERS = [] of HTTP::Handler
|
||||||
property host_binding, ssl, port, env, public_folder, logging
|
property host_binding, ssl, port, env, public_folder, logging, always_rescue, error_handler
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@host_binding = "0.0.0.0" unless @host_binding
|
@host_binding = "0.0.0.0" unless @host_binding
|
||||||
|
@ -11,6 +11,8 @@ module Kemal
|
||||||
@public_folder = "./public"
|
@public_folder = "./public"
|
||||||
@logging = true
|
@logging = true
|
||||||
@logger = nil
|
@logger = nil
|
||||||
|
@always_rescue = true
|
||||||
|
@error_handler = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def logger
|
def logger
|
||||||
|
@ -39,13 +41,21 @@ module Kemal
|
||||||
|
|
||||||
def setup_logging
|
def setup_logging
|
||||||
if @logging
|
if @logging
|
||||||
@logger = Kemal::CommonLogHandler.new(@env)
|
@logger ||= Kemal::CommonLogHandler.new(@env)
|
||||||
HANDLERS << @logger.not_nil!
|
HANDLERS << @logger.not_nil!
|
||||||
elsif @logging == false
|
else
|
||||||
@logger = Kemal::NullLogHandler.new(@env)
|
@logger = Kemal::NullLogHandler.new(@env)
|
||||||
HANDLERS << @logger.not_nil!
|
HANDLERS << @logger.not_nil!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def setup_error_handler
|
||||||
|
if @always_rescue
|
||||||
|
@error_handler ||= Kemal::CommonErrorHandler::INSTANCE
|
||||||
|
HANDLERS << @error_handler.not_nil!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.config
|
def self.config
|
||||||
|
|
9
src/kemal/exceptions.cr
Normal file
9
src/kemal/exceptions.cr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
module Kemal::Exceptions
|
||||||
|
|
||||||
|
class RouteNotFound < Exception
|
||||||
|
def initialize(context)
|
||||||
|
super "Requested path: '#{context.request.override_method as String}:#{context.request.path}' was not found."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -24,21 +24,13 @@ class Kemal::RouteHandler < HTTP::Handler
|
||||||
|
|
||||||
# Processes the route if it's a match. Otherwise renders 404.
|
# Processes the route if it's a match. Otherwise renders 404.
|
||||||
def process_request(context)
|
def process_request(context)
|
||||||
url = context.request.path.not_nil!
|
|
||||||
Kemal::Route.check_for_method_override!(context.request)
|
Kemal::Route.check_for_method_override!(context.request)
|
||||||
lookup = @tree.find radix_path(context.request.override_method as String, context.request.path)
|
lookup = @tree.find radix_path(context.request.override_method as String, context.request.path)
|
||||||
if lookup.found?
|
raise Kemal::Exceptions::RouteNotFound.new(context) unless lookup.found?
|
||||||
route = lookup.payload as Route
|
route = lookup.payload as Route
|
||||||
context.request.url_params = lookup.params
|
context.request.url_params = lookup.params
|
||||||
begin
|
context.response.print(route.handler.call(context).to_s)
|
||||||
body = route.handler.call(context).to_s
|
context
|
||||||
context.response.print body
|
|
||||||
return context
|
|
||||||
rescue ex
|
|
||||||
return render_500(context, ex.to_s)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return render_404(context)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private def radix_path(method : String, path)
|
private def radix_path(method : String, path)
|
||||||
|
@ -49,4 +41,5 @@ class Kemal::RouteHandler < HTTP::Handler
|
||||||
node = radix_path method, path
|
node = radix_path method, path
|
||||||
@tree.add node, route
|
@tree.add node, route
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue