about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-11-09 19:14:27 -0800
committerEric Wong <normalperson@yhbt.net>2009-11-11 15:46:58 -0800
commit8c104a8a9e341aaaa36bd270cf48ded2f479f5a0 (patch)
tree9e242c560676beebf2214dc36c7bb5a78ba9b1fd /lib
parentb778740240e6dbeeaf1c4cf604865170e7cb454c (diff)
downloadrainbows-8c104a8a9e341aaaa36bd270cf48ded2f479f5a0.tar.gz
Unicorn 0.94.0 got a more generic handle_error function
that's useful in the Thread* models.  The Revactor one
is a little different but similar to be worth refactoring
to match our standard pieces.
Diffstat (limited to 'lib')
-rw-r--r--lib/rainbows/base.rb18
-rw-r--r--lib/rainbows/revactor.rb40
2 files changed, 23 insertions, 35 deletions
diff --git a/lib/rainbows/base.rb b/lib/rainbows/base.rb
index 04725f0..03cf624 100644
--- a/lib/rainbows/base.rb
+++ b/lib/rainbows/base.rb
@@ -10,14 +10,6 @@ module Rainbows
     include Rainbows::Const
     G = Rainbows::G
 
-    # write a response without caring if it went out or not for error
-    # messages.
-    # TODO: merge into Unicorn::HttpServer
-    def emergency_response(client, response_str)
-      client.write_nonblock(response_str) rescue nil
-      client.close rescue nil
-    end
-
     def listen_loop_error(e)
       G.alive or return
       logger.error "Unhandled listen loop exception #{e.inspect}."
@@ -72,14 +64,8 @@ module Rainbows
     # assuming we haven't closed the socket, but don't get hung up
     # if the socket is already closed or broken.  We'll always ensure
     # the socket is closed at the end of this function
-    rescue EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
-      emergency_response(client, ERROR_500_RESPONSE)
-    rescue HttpParserError # try to tell the client they're bad
-      buf.empty? or emergency_response(client, ERROR_400_RESPONSE)
-    rescue Object => e
-      emergency_response(client, ERROR_500_RESPONSE)
-      logger.error "Read error: #{e.inspect}"
-      logger.error e.backtrace.join("\n")
+    rescue => e
+      handle_error(client, e)
     end
 
     def join_threads(threads)
diff --git a/lib/rainbows/revactor.rb b/lib/rainbows/revactor.rb
index 003b704..43dc60d 100644
--- a/lib/rainbows/revactor.rb
+++ b/lib/rainbows/revactor.rb
@@ -57,18 +57,8 @@ module Rainbows
         HttpResponse.write(client, response, out)
       end while alive and hp.reset.nil? and env.clear
       client.close
-    # if we get any error, try to write something back to the client
-    # assuming we haven't closed the socket, but don't get hung up
-    # if the socket is already closed or broken.  We'll always ensure
-    # the socket is closed at the end of this function
-    rescue EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
-      emergency_response(client, Const::ERROR_500_RESPONSE)
-    rescue HttpParserError # try to tell the client they're bad
-      buf.empty? or emergency_response(client, Const::ERROR_400_RESPONSE)
-    rescue Object => e
-      emergency_response(client, Const::ERROR_500_RESPONSE)
-      logger.error "Read error: #{e.inspect}"
-      logger.error e.backtrace.join("\n")
+    rescue => e
+      handle_error(client, e)
     end
 
     # runs inside each forked worker, this sits around and waits
@@ -114,16 +104,28 @@ module Rainbows
       end while G.alive || clients.size > 0
     end
 
-  private
-
-    # write a response without caring if it went out or not
-    # This is in the case of untrappable errors
-    def emergency_response(client, response_str)
+    # if we get any error, try to write something back to the client
+    # assuming we haven't closed the socket, but don't get hung up
+    # if the socket is already closed or broken.  We'll always ensure
+    # the socket is closed at the end of this function
+    def handle_error(client, e)
+      msg = case e
+      when EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
+        Const::ERROR_500_RESPONSE
+      when HttpParserError # try to tell the client they're bad
+        Const::ERROR_400_RESPONSE
+      else
+        logger.error "Read error: #{e.inspect}"
+        logger.error e.backtrace.join("\n")
+        Const::ERROR_500_RESPONSE
+      end
       client.instance_eval do
         # this is Revactor implementation dependent
-        @_io.write_nonblock(response_str) rescue nil
+        @_io.write_nonblock(msg)
+        close
       end
-      client.close rescue nil
+      rescue
+        nil
     end
 
     def revactorize_listeners!