Skip to content
This repository

Rack::BodyProxy should execute block even on failures. #313

Merged
merged 1 commit into from over 2 years ago

2 participants

José Valim Aaron Patterson
José Valim
Collaborator

In general, Rack frameworks are moving logic to close hooks in order
to support async behavior increasing the chance an exception will
happen on close. Most servers will actually die if there is an exception
on close, but such exceptions can also happen in the test environment.
In such cases, we can accidentally leave a mutex locked, a database
connection not collected and so forth, therefore, we need to ensure
the block is called regardless closing the body failed.

José Valim Rack::BodyProxy should execute block even on failures.
In general, Rack frameworks are moving logic to close hooks in order
to support async behavior increasing the chance an exception will
happen on close. Most servers will actually die if there is an exception
on close, but such exceptions can also happen in the test environment.
In such cases, we can accidentally leave a mutex locked, a database
connection not collected and so forth, therefore, we need to ensure
the block is called regardless closing the body failed.
b06ef82
Aaron Patterson tenderlove merged commit 6cb96fe into from January 13, 2012
Aaron Patterson tenderlove closed this January 13, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Jan 13, 2012
José Valim Rack::BodyProxy should execute block even on failures.
In general, Rack frameworks are moving logic to close hooks in order
to support async behavior increasing the chance an exception will
happen on close. Most servers will actually die if there is an exception
on close, but such exceptions can also happen in the test environment.
In such cases, we can accidentally leave a mutex locked, a database
connection not collected and so forth, therefore, we need to ensure
the block is called regardless closing the body failed.
b06ef82
This page is out of date. Refresh to see the latest.
7  lib/rack/body_proxy.rb
@@ -11,8 +11,11 @@ def respond_to?(*args)
11 11
     def close
12 12
       return if @closed
13 13
       @closed = true
14  
-      @body.close if @body.respond_to? :close
15  
-      @block.call
  14
+      begin
  15
+        @body.close if @body.respond_to? :close
  16
+      ensure
  17
+        @block.call
  18
+      end
16 19
     end
17 20
 
18 21
     def closed?
17  test/spec_body_proxy.rb
... ...
@@ -1,4 +1,5 @@
1 1
 require 'rack/body_proxy'
  2
+require 'stringio'
2 3
 
3 4
 describe Rack::BodyProxy do
4 5
   should 'call each on the wrapped body' do
@@ -32,6 +33,22 @@
32 33
     called.should.equal true
33 34
   end
34 35
 
  36
+  should 'call the passed block on close even if there is an exception' do
  37
+    object = Object.new
  38
+    def object.close() raise "No!" end
  39
+    called = false
  40
+
  41
+    begin
  42
+      proxy  = Rack::BodyProxy.new(object) { called = true }
  43
+      called.should.equal false
  44
+      proxy.close
  45
+    rescue RuntimeError => e
  46
+    end
  47
+
  48
+    raise "Expected exception to have been raised" unless e
  49
+    called.should.equal true
  50
+  end
  51
+
35 52
   should 'not close more than one time' do
36 53
     count = 0
37 54
     proxy = Rack::BodyProxy.new([]) { count += 1; raise "Block invoked more than 1 time!" if count > 1 }
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.