Permalink
Browse files

Adding rack/lilypad/rails to make catching exceptions in Rails simple…

…r, testing middleware exceptions
  • Loading branch information...
1 parent d4f7012 commit a7cee464f2987450daed596db8dce15b57838f54 @winton committed Dec 3, 2009
View
@@ -21,21 +21,8 @@ require 'rack/lilypad'
Rails::Initializer.run do |config|
config.middleware.insert_after(ActionController::Failsafe, Rack::Lilypad, 'hoptoad_api_key_goes_here')
end
-</pre>
-
-**app/controllers/application_controller.rb**:
-<pre>
-class ApplicationController < ActionController::Base
-
- def rescue_action(exception)
- super
- ENV['RACK_ENV'] = ENV['RAILS_ENV']
- request.env['rack.lilypad.component'] = params[:controller]
- request.env['rack.lilypad.action'] = params[:action]
- raise exception
- end
-end
+require 'rack/lilypad/rails'
</pre>
Sinatra
@@ -45,7 +32,7 @@ Sinatra
require 'rack/lilypad'
class MyApp < Sinatra::Application
- enable :raise_errors # not necessary for Sinatra::Base
+ enable :raise_errors # Not needed when inheriting from Sinatra::Base
use Rack::Lilypad, 'hoptoad_api_key_goes_here'
end
</pre>
View
@@ -14,5 +14,5 @@
s.name = GEM_NAME
s.platform = Gem::Platform::RUBY
s.require_path = "lib"
- s.version = "0.2.2"
+ s.version = "0.2.3"
end
@@ -0,0 +1,23 @@
+require 'rack/lilypad'
+
+module Rack
+ class Lilypad
+ module Rails
+
+ def self.included(base)
+ ENV['RACK_ENV'] = ENV['RAILS_ENV']
+ end
+
+ private
+
+ def rescue_action(exception)
+ super
+ request.env['rack.lilypad.component'] = params[:controller]
+ request.env['rack.lilypad.action'] = params[:action]
+ raise exception
+ end
+ end
+ end
+end
+
+ActionController::Base.send(:include, Rack::Lilypad::Rails)
@@ -8,15 +8,11 @@ class ApplicationController < ActionController::Base
# Scrub sensitive parameters from your log
# filter_parameter_logging :password
- def rescue_action(exception)
- super
- ENV['RACK_ENV'] = ENV['RAILS_ENV']
- request.env['rack.lilypad.component'] = params[:controller]
- request.env['rack.lilypad.action'] = params[:action]
- raise exception
+ def nothing
+ render :nothing => true
end
- def pulse
+ def test
raise TestError, 'Test'
end
end
@@ -40,4 +40,8 @@
# config.i18n.default_locale = :de
config.middleware.insert_after(ActionController::Failsafe, Rack::Lilypad, 'xxx')
-end
+ config.middleware.delete(ActionController::Failsafe) # Enabling this magically makes all the specs pass! :)
+ config.middleware.use(TestExceptionMiddleware)
+end
+
+require 'rack/lilypad/rails'
@@ -42,5 +42,6 @@
#map.connect ':controller/:action/:id'
#map.connect ':controller/:action/:id.:format'
- map.connect '/pulse', :controller => 'application', :action => 'pulse'
+ map.connect '/nothing', :controller => 'application', :action => 'nothing'
+ map.connect '/test', :controller => 'application', :action => 'test'
end
@@ -1,8 +1,13 @@
class SinatraApp < Sinatra::Base
use Rack::Lilypad, 'xxx'
+ use TestExceptionMiddleware
- get "/pulse" do
+ get "/nothing" do
+ nil
+ end
+
+ get "/test" do
raise TestError, 'Test'
end
end
@@ -0,0 +1,15 @@
+class TestExceptionMiddleware
+ def initialize(app, session_key = '_session_id')
+ @app = app
+ @session_key = session_key
+ end
+
+ def call(env)
+ req = Rack::Request.new(env)
+ if req.params['test_exception']
+ raise "raising a RuntimeError to test the middleware exception"
+ else
+ @app.call(env)
+ end
+ end
+end
@@ -5,9 +5,8 @@
include Rack::Test::Methods
before(:each) do
- ENV['RAILS_ENV'] = ENV['RACK_ENV'] = 'production'
@app = lambda { |env| raise TestError, 'Test' }
- @env = Rack::MockRequest.env_for("/pulse")
+ @env = Rack::MockRequest.env_for("/test")
@http = mock(:http)
@http.stub!(:read_timeout=)
@http.stub!(:open_timeout=)
@@ -71,15 +70,28 @@ def app
ActionController::Dispatcher.new
end
+ it "should set ENV['RACK_ENV']" do
+ ENV['RACK_ENV'].should == 'production'
+ end
+
it "should post an error to Hoptoad" do
@http.should_receive(:post)
- get "/pulse" rescue nil
+ get "/test" rescue nil
+ end
+
+ it "should re-raise the exception (with ActionController::Failsafe disabled)" do
+ lambda { get "/test" }.should raise_error(TestError)
+ end
+
+ it "should catch middleware exceptions" do
+ @http.should_receive(:post)
+ get "/nothing?test_exception=1" rescue nil
end
it "should not do anything if non-production environment" do
ENV['RACK_ENV'] = 'development'
@http.should_not_receive(:post)
- get "/pulse" rescue nil
+ get "/test" rescue nil
end
end
@@ -89,19 +101,28 @@ def app
SinatraApp.new
end
+ before(:each) do
+ ENV['RACK_ENV'] = 'production'
+ end
+
it "should post an error to Hoptoad" do
@http.should_receive(:post)
- get "/pulse" rescue nil
+ get "/test" rescue nil
end
it "should re-raise the exception" do
- lambda { get "/pulse" }.should raise_error(TestError)
+ lambda { get "/test" }.should raise_error(TestError)
+ end
+
+ it "should catch middleware exceptions" do
+ @http.should_receive(:post)
+ get "/nothing?test_exception=1" rescue nil
end
it "should not do anything if non-production environment" do
ENV['RACK_ENV'] = 'development'
@http.should_not_receive(:post)
- get "/pulse" rescue nil
+ get "/test" rescue nil
end
end
end
View
@@ -10,6 +10,10 @@
require 'rack/test'
require 'sinatra/base'
+# Depend on rack/lilypad/rails to set ENV['RACK_ENV'] from this
+ENV['RAILS_ENV'] = 'production'
+
+require File.expand_path("#{SPEC}/fixtures/test_exception_middleware")
require File.expand_path("#{SPEC}/fixtures/rails/config/environment")
require File.expand_path("#{SPEC}/fixtures/sinatra")

0 comments on commit a7cee46

Please sign in to comment.