Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Rescue from exceptions raised by the metastore and pass on the request

  • Loading branch information...
commit 7bcd0cec2723b91ee0d557153134d457219895ba 1 parent e51b1fb
@josh josh authored
Showing with 57 additions and 12 deletions.
  1. +32 −12 lib/rack/cache/context.rb
  2. +25 −0 test/context_test.rb
View
44 lib/rack/cache/context.rb
@@ -133,8 +133,12 @@ def pass
# Invalidate POST, PUT, DELETE and all methods not understood by this cache
# See RFC2616 13.10
def invalidate
- record :invalidate
metastore.invalidate(@request, entitystore)
+ rescue Exception => e
+ log_error(e)
+ pass
+ else
+ record :invalidate
pass
end
@@ -147,18 +151,26 @@ def lookup
if @request.no_cache? && allow_reload?
record :reload
fetch
- elsif entry = metastore.lookup(@request, entitystore)
- if fresh_enough?(entry)
- record :fresh
- entry.headers['Age'] = entry.age.to_s
- entry
+ else
+ begin
+ entry = metastore.lookup(@request, entitystore)
+ rescue Exception => e
+ log_error(e)
+ return pass
+ end
+ if entry
+ if fresh_enough?(entry)
+ record :fresh
+ entry.headers['Age'] = entry.age.to_s
+ entry
+ else
+ record :stale
+ validate(entry)
+ end
else
- record :stale
- validate(entry)
+ record :miss
+ fetch
end
- else
- record :miss
- fetch
end
end
@@ -225,9 +237,17 @@ def fetch
# Write the response to the cache.
def store(response)
- record :store
metastore.store(@request, response, entitystore)
response.headers['Age'] = response.age.to_s
+ rescue Exception => e
+ log_error(e)
+ nil
+ else
+ record :store
+ end
+
+ def log_error(exception)
+ @env['rack.errors'].write("cache error: #{exception.message}\n#{exception.backtrace.join("\n")}\n")
end
end
end
View
25 test/context_test.rb
@@ -746,4 +746,29 @@
response['X-Response-Count'].should.equal '3'
end
end
+
+ it 'passes if there was a metastore exception' do
+ respond_with 200, 'Cache-Control' => 'max-age=10000' do |req,res|
+ res.body = ['Hello World']
+ end
+
+ get '/'
+ response.should.be.ok
+ response.body.should.equal 'Hello World'
+ cache.trace.should.include :store
+
+ get '/' do |cache|
+ cache.meta_def(:metastore) { raise Timeout::Error }
+ end
+ response.should.be.ok
+ response.body.should.equal 'Hello World'
+ cache.trace.should.include :pass
+
+ post '/' do |cache|
+ cache.meta_def(:metastore) { raise Timeout::Error }
+ end
+ response.should.be.ok
+ response.body.should.equal 'Hello World'
+ cache.trace.should.include :pass
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.