require File.dirname(__FILE__) + '/../spec_helper' module RosettaQueue describe ExceptionHandler do after(:each) do ExceptionHandler.reset_handlers end describe "::handle" do it "runs the given block returning the block's return value" do ExceptionHandler::handle do "foo" end.should == "foo" end it "delegates raised exceptions to each related registered handler" do # given ExceptionHandler::register(:consuming, registered_handler = mock('exception handling')) ExceptionHandler::register(:consuming, registered_handler2 = mock('exception handling')) exception = StandardError.new # expect registered_handler.should_receive(:handle).with(exception, anything) registered_handler2.should_receive(:handle).with(exception, anything) # when ExceptionHandler::handle(:consuming) do raise exception end end it "does not delegate raised exceptions to unrelated handlers" do # given ExceptionHandler::register(:consuming, consuming_handler = mock('consumner handling')) ExceptionHandler::register(:publishing, publishing_handler = mock('publishing handling')) exception = StandardError.new # expect consuming_handler.should_receive(:handle).with(exception, anything) publishing_handler.should_not_receive(:handle) # when ExceptionHandler::handle(:consuming) do raise exception end end it "delegates all types of messaging exceptions to handlers registered under ':all'" do # given ExceptionHandler::register(:all, messaging_handler = mock('global message exception handling')) exception = StandardError.new # expect messaging_handler.should_receive(:handle).with(exception, anything).twice # when ExceptionHandler::handle(:consuming) { raise exception } ExceptionHandler::handle(:publishing) { raise exception } end it "passes any additional information (in form of a hash) to the registered handlers" do # given ExceptionHandler::register(:all, messaging_handler = mock('global message exception handling')) info_hash = {:message => "this caused failure", :foo => "bar"} # expect messaging_handler.should_receive(:handle).with(anything, info_hash) # when ExceptionHandler::handle(:consuming, info_hash) { raise "FAIL" } end it "accepts a lambda for info and will pass it's evaluation along to the registered handlers" do # given ExceptionHandler::register(:all, messaging_handler = mock('global message exception handling')) info_hash = {:message => "this caused failure", :foo => "bar"} # expect messaging_handler.should_receive(:handle).with(anything, info_hash) # when ExceptionHandler::handle(:consuming, lambda { info_hash }) { raise "FAIL" } end it "reraises the error when no handlers have been registed for the given action" do ExceptionHandler::register(:consuming, consuming_handler = mock('consumner handling')) running do ExceptionHandler::handle(:publishing, {}) { raise "Foo" } end.should raise_error(RuntimeError) end end describe "::register" do # see the examples for ::handle as well- since they are related. it "takes an exception handling block in place of a class" do # given ExceptionHandler::register(:all) do |exception, info| RosettaQueue.logger.error "whoops" end # expect RosettaQueue.logger.should_receive(:error).with("whoops") # when ExceptionHandler::handle(:consuming) { raise "FAIL" } end end end end