@@ -803,7 +803,7 @@ def restart_outdated_workers
803803 # assuming we haven't closed the socket, but don't get hung up
804804 # if the socket is already closed or broken. We'll always ensure
805805 # the socket is closed at the end of this function
806- def handle_error ( client , e )
806+ def handle_error ( client , e , response_written )
807807 code = case e
808808 when EOFError , Errno ::ECONNRESET , Errno ::EPIPE , Errno ::ENOTCONN
809809 # client disconnected on us and there's nothing we can do
@@ -817,7 +817,7 @@ def handle_error(client, e)
817817 Pitchfork . log_error ( @logger , "app error" , e )
818818 500
819819 end
820- if code
820+ if code && ! response_written
821821 client . write_nonblock ( err_response ( code , @request . response_start_sent ) , exception : false )
822822 end
823823 client . close
@@ -842,6 +842,7 @@ def e100_response_write(client, env)
842842 # once a client is accepted, it is processed in its entirety here
843843 # in 3 easy steps: read request, call app, write app response
844844 def process_client ( client , worker , timeout_handler )
845+ response_written = false
845846 env = nil
846847 @request = Pitchfork ::HttpParser . new
847848 env = @request . read ( client )
@@ -876,6 +877,7 @@ def process_client(client, worker, timeout_handler)
876877 end
877878 @request . headers? or headers = nil
878879 http_response_write ( client , status , headers , body , @request )
880+ response_written = true
879881 ensure
880882 body . respond_to? ( :close ) and body . close
881883 end
@@ -889,7 +891,7 @@ def process_client(client, worker, timeout_handler)
889891 end
890892 env
891893 rescue => application_error
892- handle_error ( client , application_error )
894+ handle_error ( client , application_error , response_written )
893895 env
894896 ensure
895897 if env
0 commit comments