mirror of
				https://gitea.invidious.io/iv-org/shard-kemal.git
				synced 2024-08-15 00:53:36 +00:00 
			
		
		
		
	Start implementing error block
This commit is contained in:
		
							parent
							
								
									35239dfaa0
								
							
						
					
					
						commit
						e6d9311895
					
				
					 7 changed files with 71 additions and 25 deletions
				
			
		|  | @ -2,10 +2,27 @@ require "./spec_helper" | ||||||
| 
 | 
 | ||||||
| describe "Kemal::CommonExceptionHandler" do | describe "Kemal::CommonExceptionHandler" do | ||||||
|   it "renders 404 on route not found" do |   it "renders 404 on route not found" do | ||||||
|     common_exception_handler = Kemal::CommonExceptionHandler::INSTANCE |     get "/" do |env| | ||||||
|     request = HTTP::Request.new("GET", "/?message=world") |       "Hello" | ||||||
|     io_with_context = create_request_and_return_io(common_exception_handler, request) |     end | ||||||
|     client_response = HTTP::Client::Response.from_io(io_with_context, decompress: false) | 
 | ||||||
|  |     request = HTTP::Request.new("GET", "/asd") | ||||||
|  |     client_response = call_request_on_app(request) | ||||||
|     client_response.status_code.should eq 404 |     client_response.status_code.should eq 404 | ||||||
|   end |   end | ||||||
|  | 
 | ||||||
|  |   it "renders custom error" do | ||||||
|  |     error 403 do | ||||||
|  |       "403 error" | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     get "/" do |env| | ||||||
|  |       env.response.status_code = 403 | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     request = HTTP::Request.new("GET", "/") | ||||||
|  |     client_response = call_request_on_app(request) | ||||||
|  |     client_response.status_code.should eq 403 | ||||||
|  |     client_response.body.should eq "403 error" | ||||||
|  |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ require "./kemal/*" | ||||||
| require "./kemal/middleware/*" | require "./kemal/middleware/*" | ||||||
| 
 | 
 | ||||||
| module Kemal | module Kemal | ||||||
| 
 |  | ||||||
|   # The command to run a `Kemal` application. |   # The command to run a `Kemal` application. | ||||||
|   def self.run |   def self.run | ||||||
|     Kemal::CLI.new |     Kemal::CLI.new | ||||||
|  | @ -13,6 +12,10 @@ module Kemal | ||||||
|     config.server = HTTP::Server.new(config.host_binding.not_nil!, config.port, config.handlers) |     config.server = HTTP::Server.new(config.host_binding.not_nil!, config.port, config.handlers) | ||||||
|     config.server.not_nil!.ssl = config.ssl |     config.server.not_nil!.ssl = config.ssl | ||||||
| 
 | 
 | ||||||
|  |     error 404 do |env| | ||||||
|  |       render_404(env) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|     # Test environment doesn't need to have signal trap, built-in images, and logging. |     # Test environment doesn't need to have signal trap, built-in images, and logging. | ||||||
|     unless config.env == "test" |     unless config.env == "test" | ||||||
|       Signal::INT.trap { |       Signal::INT.trap { | ||||||
|  |  | ||||||
|  | @ -1,18 +1,22 @@ | ||||||
| class Kemal::CommonExceptionHandler < HTTP::Handler | module Kemal | ||||||
|  |   class CommonExceptionHandler < HTTP::Handler | ||||||
|     INSTANCE = new |     INSTANCE = new | ||||||
| 
 | 
 | ||||||
|     def call(context) |     def call(context) | ||||||
|       begin |       begin | ||||||
|       call_next context |         call_next(context) | ||||||
|       rescue ex : Kemal::Exceptions::RouteNotFound |       rescue ex : Kemal::Exceptions::RouteNotFound | ||||||
|  |         return Kemal.config.error_handlers[404].call(context) | ||||||
|  |       rescue ex1 : Kemal::Exceptions::CustomException | ||||||
|  |         status_code = ex1.context.response.status_code | ||||||
|  |         return Kemal.config.error_handlers[status_code].call(context) if Kemal.config.error_handlers.key?(status_code) | ||||||
|  |       rescue ex2 | ||||||
|  |         Kemal.config.error_handlers[500].call(context) if Kemal.config.error_handlers.key?(500) | ||||||
|         context.response.content_type = "text/html" |         context.response.content_type = "text/html" | ||||||
|       Kemal.config.logger.write("Exception: #{ex.inspect_with_backtrace}\n") |         Kemal.config.logger.write("Exception: #{ex2.inspect_with_backtrace}\n") | ||||||
|       return render_404(context) |  | ||||||
|     rescue ex |  | ||||||
|       context.response.content_type = "text/html" |  | ||||||
|       Kemal.config.logger.write("Exception: #{ex.inspect_with_backtrace}\n") |  | ||||||
|         verbosity = Kemal.config.env == "production" ? false : true |         verbosity = Kemal.config.env == "production" ? false : true | ||||||
|       return render_500(context, ex.inspect_with_backtrace, verbosity) |         return render_500(context, ex2.inspect_with_backtrace, verbosity) | ||||||
|  |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -2,11 +2,12 @@ module Kemal | ||||||
|   class Config |   class Config | ||||||
|     INSTANCE       = Config.new |     INSTANCE       = Config.new | ||||||
|     HANDLERS       = [] of HTTP::Handler |     HANDLERS       = [] of HTTP::Handler | ||||||
|  |     ERROR_HANDLERS = {} of Int32 => HTTP::Server::Context -> String | ||||||
|     @ssl : OpenSSL::SSL::Context? |     @ssl : OpenSSL::SSL::Context? | ||||||
|     @server : HTTP::Server? |     @server : HTTP::Server? | ||||||
| 
 | 
 | ||||||
|     property host_binding, ssl, port, env, public_folder, logging, |     property host_binding, ssl, port, env, public_folder, logging, | ||||||
|       always_rescue, serve_static, server |       always_rescue, serve_static, server, error_handler | ||||||
| 
 | 
 | ||||||
|     def initialize |     def initialize | ||||||
|       @host_binding = "0.0.0.0" |       @host_binding = "0.0.0.0" | ||||||
|  | @ -19,8 +20,6 @@ module Kemal | ||||||
|       @error_handler = nil |       @error_handler = nil | ||||||
|       @always_rescue = true |       @always_rescue = true | ||||||
|       @run = false |       @run = false | ||||||
|       @ssl = nil |  | ||||||
|       @server = nil |  | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     def logger |     def logger | ||||||
|  | @ -47,6 +46,14 @@ module Kemal | ||||||
|       HANDLERS << handler |       HANDLERS << handler | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  |     def error_handlers | ||||||
|  |       ERROR_HANDLERS | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def add_error_handler(status_code, &handler : HTTP::Server::Context -> _) | ||||||
|  |       ERROR_HANDLERS[status_code] = ->(context : HTTP::Server::Context) { handler.call(context).to_s } | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|     def setup |     def setup | ||||||
|       setup_log_handler |       setup_log_handler | ||||||
|       setup_error_handler |       setup_error_handler | ||||||
|  |  | ||||||
|  | @ -9,3 +9,7 @@ HTTP_METHODS = %w(get post put patch delete options) | ||||||
| def ws(path, &block : HTTP::WebSocket, HTTP::Server::Context -> Void) | def ws(path, &block : HTTP::WebSocket, HTTP::Server::Context -> Void) | ||||||
|   Kemal::WebSocketHandler.new path, &block |   Kemal::WebSocketHandler.new path, &block | ||||||
| end | end | ||||||
|  | 
 | ||||||
|  | def error(status_code, &block : HTTP::Server::Context -> _) | ||||||
|  |   Kemal.config.add_error_handler status_code, &block | ||||||
|  | end | ||||||
|  |  | ||||||
|  | @ -4,4 +4,12 @@ module Kemal::Exceptions | ||||||
|       super "Requested path: '#{context.request.override_method as String}:#{context.request.path}' was not found." |       super "Requested path: '#{context.request.override_method as String}:#{context.request.path}' was not found." | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  | 
 | ||||||
|  |   class CustomException < Exception | ||||||
|  |     getter context | ||||||
|  | 
 | ||||||
|  |     def initialize(@context) | ||||||
|  |       super "Rendered error with #{@context.response.status_code}" | ||||||
|  |     end | ||||||
|  |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -31,9 +31,12 @@ 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) | ||||||
|     raise Kemal::Exceptions::RouteNotFound.new(context) unless context.route_defined? |     return raise Kemal::Exceptions::RouteNotFound.new(context) unless context.route_defined? | ||||||
|     route = context.route_lookup.payload as Route |     route = context.route_lookup.payload as Route | ||||||
|     context.response.print(route.handler.call(context)) |     context.response.print(route.handler.call(context)) | ||||||
|  |     if Kemal.config.error_handlers.has_key?(context.response.status_code) | ||||||
|  |       return raise Kemal::Exceptions::CustomException.new(context) | ||||||
|  |     end | ||||||
|     context |     context | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue