Feature #5856

Feature: Raise any object

Added by Kurt Stephens over 2 years ago. Updated over 1 year ago.

[ruby-core:41950]
Status:Rejected
Priority:Normal
Assignee:Yukihiro Matsumoto
Category:core
Target version:next minor

Description

Feature: Raise any object

= Proposal

The ability to raise any object that conforms to the protocol of Exception.

= Problem

  • The Exception subclass hierarchy is well-established.
  • CRuby does not allow any object that behaves as an Exception to be raised, it must be a subclass of Exception.
  • 3rd-party code often rescues Exception; e.g. for error recovery, retry and/or logging.
  • Users need the ability to raise objects that would not normally be rescued by any code; e.g.: hard timeouts or custom signal handlers in an application.

= Solution

  • ruby/eval.c: Remove makeexception() assertion rbobjiskindof(mesg, rbmRaiseable).

= Implementation

= Example

  • See test/ruby/testraiseany.rb

= See also

trunk-raise-any.diff Magnifier (3.97 KB) Kurt Stephens, 01/07/2012 06:52 AM


Related issues

Related to ruby-trunk - Feature #5818: Feature: Raiseable Rejected 12/28/2011

History

#1 Updated by Kurt Stephens over 2 years ago

Attached patch.

#2 Updated by Yukihiro Matsumoto over 2 years ago

Hi,

In message "Re: [ruby-trunk - Feature #5856][Open] Feature: Raise any object"
on Sat, 7 Jan 2012 06:51:53 +0900, Kurt Stephens redmine@ruby-lang.org writes:

|= Problem
|
|* The Exception subclass hierarchy is well-established.
|* CRuby does not allow any object that behaves as an Exception to be raised, it must be a subclass of Exception.
|* 3rd-party code often rescues Exception; e.g. for error recovery, retry and/or logging.
|* Users need the ability to raise objects that would not normally be rescued by any code;
| e.g.: hard timeouts or custom signal handlers in an application.

Are you saying that we should be able to raise exception that can not
(normally) be caught? I don't think it's good practice. For such
purpose, use catch/throw. Or is there any other (preferably concrete)
use-case?

                        matz.

#3 Updated by Nobuyoshi Nakada over 2 years ago

  • Category set to core
  • Status changed from Open to Feedback
  • Assignee set to Yukihiro Matsumoto

=begin
* 3rd-party code often rescues (({Exception})); e.g. for error recovery, retry and/or logging.
* Users need the ability to raise objects that would not normally be rescued by ((any)) code;
e.g.: hard timeouts or custom signal handlers in an application.

It doesn't sound to make sense.
Then such 3rd-party code will just rescue (({Object})) (or (({BasicObject}))) instead of (({Exception})), won't it?

What you expect seems something different from exceptions to me.
=end

#4 Updated by Yukihiro Matsumoto over 2 years ago

C++ style raising any object does not seem like "exception handling" for me. Besides that, since exception dispatch is based on inheritance hierarchy, it is natural (for me at least) to use Exception as a root of all exceptions.

#5 Updated by Kurt Stephens about 2 years ago

One can rescue Exception (or Object); this also rescues SystemExit, Interrupt, etc. There is plenty of code out there that rescues Exception but does not rethrow SystemExit and Interrupt; it's a common design mistake. IMO, SystemExit is really a global control flow mechanism, not an exceptional condition; not debating this particular issue.

The issue is 3rd-parties often rescue Exception as a catch-all, to provide fallback, logging, etc; thus it prevents the raising objects that 3rd parties should never rescue accidentally. rescue Object will trap everything and is usually considered bad style. This patch does not prevent it. Rather this patch, prevents 3rd-party code from accidentally rescuing exceptional conditions that they had not designed for.

Examples of exceptional control flows that 3rd-parties should not rescue accidentally via rescue Exception:

1) application container management
2) controlled termination of runaway worker process
3) hard Timeouts, that if incorrectly rescued, prevent a system from behaving according to real-world timing constraints.

Removing the "only Exceptions can be thrown" constraint increases flexibility; it allows objects that quack like an Exception to be thrown.

Exception is effectively a fragile base class, forcefully tied to the run-time; it prevents the use of the exception handling mechanism via duck-typing.

#6 Updated by Yusuke Endoh over 1 year ago

  • Target version set to next minor

#7 Updated by Yukihiro Matsumoto over 1 year ago

  • Status changed from Feedback to Rejected

If we allow raising non Exception object, the library authors will catch Object (or even BasicObject), and this time we will have no work around. So, it's matter of disciplined exception raising/handling. As non-local exit not to be handled, use throw, and as exception handler, do not use Exception.

Matz.

Also available in: Atom PDF