diff --git a/History.md b/History.md index 556df6bd0a..af2bf32210 100644 --- a/History.md +++ b/History.md @@ -9,6 +9,7 @@ * Prevent connections from entering Reactor after shutdown begins ([#2377]) * Fix error backtrace debug logging && Do not log request dump if it is not parsed ([#2376]) * Split TCP_CORK and TCP_INFO ([#2372]) + * Do not log EOFError when a client connection is closed without write (#2384) * Refactor * Change Events#ssl_error signature from (error, peeraddr, peercert) to (error, ssl_socket) ([#2375]) diff --git a/lib/puma/client.rb b/lib/puma/client.rb index 4289f592c8..f4f075b85d 100644 --- a/lib/puma/client.rb +++ b/lib/puma/client.rb @@ -157,7 +157,9 @@ def try_to_finish data = @io.read_nonblock(CHUNK_SIZE) rescue IO::WaitReadable return false - rescue SystemCallError, IOError, EOFError + rescue EOFError + # Swallow error, don't log + rescue SystemCallError, IOError raise ConnectionError, "Connection error detected during read" end diff --git a/lib/puma/server.rb b/lib/puma/server.rb index 804011e3ca..a6095c49e5 100644 --- a/lib/puma/server.rb +++ b/lib/puma/server.rb @@ -246,7 +246,11 @@ def run(background=true) client.close @events.parse_error e, client - rescue ConnectionError, EOFError, ThreadPool::ForceShutdown => e + rescue EOFError => e + client.close + + # Swallow, do not log + rescue ConnectionError, ThreadPool::ForceShutdown => e client.close @events.connection_error e, client diff --git a/test/test_puma_server.rb b/test/test_puma_server.rb index 0953d6deb1..58faf2440e 100644 --- a/test/test_puma_server.rb +++ b/test/test_puma_server.rb @@ -256,6 +256,17 @@ def test_doesnt_print_backtrace_in_production assert_match(/HTTP\/1.0 500 Internal Server Error/, data) end + + def test_eof_on_connection_close_is_not_logged_as_an_error + server_run + + new_connection.close # Make a connection and close without writing + + @server.stop(true) + stderr = @events.stderr.string + assert stderr.empty?, "Expected stderr from server to be empty but it was #{stderr.inspect}" + end + def test_force_shutdown_custom_error_message handler = lambda {|err, env, status| [500, {"Content-Type" => "application/json"}, ["{}\n"]]} @server = Puma::Server.new @app, @events, {:lowlevel_error_handler => handler, :force_shutdown_after => 2}