Specifying a specific error is re-raised


#1

Hi

I’ve got code I want to intercept all errors (to report them) but re-
raise them immediately. Currently the raise_error matcher doesn’t
support matching against instances of exception classes, so I’ve done
this to prove that the actual exception was re-raised:

     describe "when the update is unsuccessful" do
       class WeirdError < StandardError; end

       before(:each) do
         @error = WeirdError.new("Error")
         @server.stub!(:check_feeds).and_raise(@error)
       end

       it "should re-raise the exception" do
         lambda { @connection.receive_data("UPDATE\n") }.
           should raise_error(WeirdError)
       end
     end

Few questions:

Is this an appropriate behaviour to spec?

If so, is this currently the best way to do it?

If so, would exception instance matching be useful?

Thanks
Ashley


http://www.patchspace.co.uk/


#2

On Tue, Oct 7, 2008 at 8:57 AM, Ashley M.
removed_email_address@domain.invalid wrote:

     before(:each) do

Few questions:

Is this an appropriate behaviour to spec?

Hmmm, should inappropriate behaviour be spec’d? :slight_smile:

Code examples are not politically correct. If you want your app to
behave some way, there should be a way to spec it.

If so, is this currently the best way to do it?

If so, would exception instance matching be useful?

Check out http://rspec.info/rdoc/classes/Spec/Matchers.html#M000434

I see that it is incomplete, because you can use just a string or
regexp if you want (w/o the error itself). I’ll adjust for the next
release.

Regardless, if you really care about the specific instance you can do
this:

lambda {
@connection.receive_data(“UPDATE\n”)
}.should raise_error {|error| error.should equal(@error)}

If what you care about is the message, you can expect specific
messages using strings or regexps:

lambda {
@connection.receive_data(“UPDATE\n”)
}.should raise_error(“with this message”)

lambda {
@connection.receive_data(“UPDATE\n”)
}.should raise_error(/with a message containing this/)

lambda {
@connection.receive_data(“UPDATE\n”)
}.should raise_error(OfThisErrorType, “with this message”)

lambda {
@connection.receive_data(“UPDATE\n”)
}.should raise_error(OfThisErrorType, with a message containing this/)

Cheers,
David


#3

On 7 Oct 2008, at 15:33, David C. wrote:

Regardless, if you really care about the specific instance you can
do this:

lambda {
@connection.receive_data(“UPDATE\n”)
}.should raise_error {|error| error.should equal(@error)}

If what you care about is the message, you can expect specific
messages using strings or regexps:

Thanks - that snippet does exactly what I want. Basically I want tee
pipe-fitting for errors - the code now looks like this:

 class Connection < EventMachine::Connection
   attr_accessor :server

   def receive_data(data)
     if data.chomp == "UPDATE"
       handle_update
     else
       send_data("ERROR: Unknown command\n")
     end
   end

   def unbind
     raise @error if @error
   end

   private

   def handle_update
     server.check_feeds
   rescue StandardError => @error
     send_data("ERROR: #{@error.to_s}\n")
     close_connection_after_writing
   else
     send_data("OK\n")
   end
 end

So I don’t care about the exception beyond extracting enough data to
feed back through the socket.

Cheers
Ashley


http://www.patchspace.co.uk/