From e424eaf0528d6c6b60c4ae81086d96c4f153ce03 Mon Sep 17 00:00:00 2001 From: Arthur Neves Date: Mon, 17 Feb 2014 12:07:17 -0500 Subject: [PATCH] Add config to customize the default error message Add a lowlevel_error_handler, so we can customize the default error message. example: ``` lowlevel_error_handler do [302, {'Content-Type' => 'text', 'Location' => 'foo.html'}, ['302 found']] end ``` [fix #458] --- lib/puma/configuration.rb | 9 +++++++++ lib/puma/server.rb | 6 +++++- test/config/app.rb | 4 ++++ test/test_config.rb | 10 ++++++++++ test/test_puma_server.rb | 17 +++++++++++++++++ 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lib/puma/configuration.rb b/lib/puma/configuration.rb index 23249111..d8fdf87b 100644 --- a/lib/puma/configuration.rb +++ b/lib/puma/configuration.rb @@ -327,6 +327,15 @@ module Puma def preload_app!(answer=true) @options[:preload_app] = answer end + + # Use +obj+ or +block+ as the low lever error handler. This allows a config file to + # change the default error on the server. + # + def lowlevel_error_handler(obj=nil, &block) + obj ||= block + raise "Provide either a #call'able or a block" unless obj + @options[:lowlevel_error_handler] = obj + end end end end diff --git a/lib/puma/server.rb b/lib/puma/server.rb index 4ddd7c43..3b6fa498 100644 --- a/lib/puma/server.rb +++ b/lib/puma/server.rb @@ -330,7 +330,7 @@ module Puma # :nodoc: def handle_check - cmd = @check.read(1) + cmd = @check.read(1) case cmd when STOP_COMMAND @@ -707,6 +707,10 @@ module Puma # A fallback rack response if +@app+ raises as exception. # def lowlevel_error(e) + if handler = @options[:lowlevel_error_handler] + return handler.call(e) + end + if @leak_stack_on_error [500, {}, ["Puma caught this error: #{e.message} (#{e.class})\n#{e.backtrace.join("\n")}"]] else diff --git a/test/config/app.rb b/test/config/app.rb index ec51a190..8f49baf9 100644 --- a/test/config/app.rb +++ b/test/config/app.rb @@ -1,3 +1,7 @@ app do |env| [200, {}, ["embedded app"]] end + +lowlevel_error_handler do |err| + [200, {}, ["error page"]] +end diff --git a/test/test_config.rb b/test/test_config.rb index 8da2722d..8dd67994 100644 --- a/test/test_config.rb +++ b/test/test_config.rb @@ -13,4 +13,14 @@ class TestConfigFile < Test::Unit::TestCase assert_equal [200, {}, ["embedded app"]], app.call({}) end + + def test_lowleve_error_handler_DSL + opts = { :config_file => "test/config/app.rb" } + conf = Puma::Configuration.new opts + conf.load + + app = conf.options[:lowlevel_error_handler] + + assert_equal [200, {}, ["error page"]], app.call({}) + end end diff --git a/test/test_puma_server.rb b/test/test_puma_server.rb index 126d9244..218936f6 100644 --- a/test/test_puma_server.rb +++ b/test/test_puma_server.rb @@ -220,6 +220,23 @@ class TestPumaServer < Test::Unit::TestCase data = sock.read assert_not_match(/don't leak me bro/, data) + assert_match(/HTTP\/1.0 500 Internal Server Error/, data) + end + + def test_prints_custom_error + @events = Puma::Events.strings + re = lambda { |err| [302, {'Content-Type' => 'text', 'Location' => 'foo.html'}, ['302 found']] } + @server = Puma::Server.new @app, @events, {lowlevel_error_handler: re} + + @server.app = proc { |e| raise "don't leak me bro" } + @server.add_tcp_listener @host, @port + @server.run + + sock = TCPSocket.new @host, @port + sock << "GET / HTTP/1.0\r\n\r\n" + + data = sock.read + assert_match(/HTTP\/1.0 302 Found/, data) end def test_custom_http_codes_10