From: Rodrigo Rosenfeld Rosas Date: 2014-08-05T22:19:50-03:00 Subject: [ruby-core:64214] Re: Asking for clarification for exception handling usage This is a multi-part message in MIME format. --------------020002020303070108080801 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Thanks a lot, Matthew. So, in your opinion if the exception class is a String this should be considered a bug, right? This happens in a branch of my project while running one test. I could try to isolate the issue so that I could create a bug report if you will. From the discussion below it indeed seems like a bug if the cause is an string rather than an exception: https://bugs.ruby-lang.org/issues/8257 I'll see if I can find some time to dig into this bug then. Thank you very much! Rodrigo. On 05-08-2014 19:28, Matthew Kerwin wrote: > To answer the first half of your question, the "cause" is an > underlying exception (inherited from $!), so you can use it to chain > errors. For example: > > begin > begin > raise 'foo' > rescue => foo > raise 'bar' > end > rescue => bar > end > bar #=> # > bar.cause == foo #=> true > > As to the second half, the third parameter to #raise is an > optionally-overridden backtrace: > > begin > raise RuntimeError, 'baz', %w[a b c] > rescue => ex > end > ex.backtrace #=> ["a", "b", "c"] > > Passing an exception instance to #raise does the following: > > begin > begin > raise 'foo' > rescue => foo > raise foo # re-raise > end > rescue => bar > end > foo.__id__ # => 70351312183760 > bar.__id__ # => 70351312183760 > > begin > begin > raise 'foo' > rescue => foo > raise foo, 'bar' # copy and raise > end > rescue => bar > end > foo.__id__ # => 70071384070800 > bar.__id__ # => 70071384070620 > bar.cause == foo # => true > > > In the first case the backtrace for both fooand barlists line 3; in > the second they have line 3 and 5 respectively. I've never heard of an > exception's #cause returning anything but an Exception instance or nil. > ��� > > On 6 August 2014 06:01, Rodrigo Rosenfeld Rosas > wrote: > > I've created a ticket for that but didn't get any feedback so I > decided to try asking in another way: > > https://bugs.ruby-lang.org/issues/10110 > > I'd like to understand what is Exception#cause and what exactly > does the third parameter of Kernel#raise. > > I've seen a code calling raise exception_instance, message rather > than passing the exception class and the cause for the handled > exception was a string rather than an Exception. I don't even know > if this is a bug and if raise should fail if you pass an exception > instance with a message as I don't really understand how exception > handling works in Ruby and what to expect for Exception#cause and > how to properly wrap an exception for logging purposes... > > If you could at least explain what Exception#cause is supposed to > carry on and what the third argument of Kernel#raise does exactly > by the specs I'd be a lot grateful. > > Thanks in advance, > Rodrigo. > > > > > -- > Matthew Kerwin > http://matthew.kerwin.net.au/ --------------020002020303070108080801 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8bit
Thanks a lot, Matthew. So, in your opinion if the exception class is a String this should be considered a bug, right?

This happens in a branch of my project while running one test. I could try to isolate the issue so that I could create a bug report if you will.

From the discussion below it indeed seems like a bug if the cause is an string rather than an exception:

https://bugs.ruby-lang.org/issues/8257

I'll see if I can find some time to dig into this bug then.

Thank you very much!

Rodrigo.

On 05-08-2014 19:28, Matthew Kerwin wrote:
To answer the first half of your question, the "cause" is an underlying exception (inherited from $!), so you can use it to chain errors. For example:

�� begin
�� �� begin
�� �� �� raise 'foo'
�� �� rescue => foo
�� �� �� raise 'bar'
�� �� end
�� rescue => bar
�� end
�� bar #=> #<RuntimeError: bar>
�� bar.cause == foo #=> true

As to the second half, the third parameter to #raise is an optionally-overridden backtrace:

�� begin
�� �� raise RuntimeError, 'baz', %w[a b c]
�� rescue => ex
�� end
�� ex.backtrace #=> ["a", "b", "c"]

Passing an exception instance to #raise does the following:

�� begin
�� �� begin
�� �� �� raise 'foo'
�� �� rescue => foo
�� �� �� raise foo # re-raise
�� �� end
�� rescue => bar
�� end
�� foo.__id__��# => 70351312183760
�� bar.__id__��# => 70351312183760

�� begin
�� �� begin
�� �� �� raise 'foo'
�� �� rescue => foo
�� �� �� raise foo, 'bar' # copy and raise
�� �� end
�� rescue => bar
�� end
�� foo.__id__��# =>��70071384070800
�� bar.__id__��# =>��70071384070620
�� bar.cause == foo # => true


In the first case the backtrace for both foo and bar lists line 3; in the second they have line 3 and 5 respectively. I've never heard of an exception's #cause returning anything but an Exception instance or nil.
���

On 6 August 2014 06:01, Rodrigo Rosenfeld Rosas <rr.rosas@gmail.com> wrote:
I've created a ticket for that but didn't get any feedback so I decided to try asking in another way:

https://bugs.ruby-lang.org/issues/10110

I'd like to understand what is Exception#cause and what exactly does the third parameter of Kernel#raise.

I've seen a code calling raise exception_instance, message rather than passing the exception class and the cause for the handled exception was a string rather than an Exception. I don't even know if this is a bug and if raise should fail if you pass an exception instance with a message as I don't really understand how exception handling works in Ruby and what to expect for Exception#cause and how to properly wrap an exception for logging purposes...

If you could at least explain what Exception#cause is supposed to carry on and what the third argument of Kernel#raise does exactly by the specs I'd be a lot grateful.

Thanks in advance,
Rodrigo.




--
�� Matthew Kerwin
�� http://matthew.kerwin.net.au/

--------------020002020303070108080801--