Project

General

Profile

Actions

Feature #5856

closed

Feature: Raise any object

Added by kstephens (Kurt Stephens) about 12 years ago. Updated over 11 years ago.

Status:
Rejected
Target version:
[ruby-core:41950]

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 make_exception() assertion rb_obj_is_kind_of(mesg, rb_mRaiseable).

= Implementation

= Example

  • See test/ruby/test_raise_any.rb

= See also


Files

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

Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #5818: Feature: RaiseableRejected12/28/2011Actions

Updated by matz (Yukihiro Matsumoto) about 12 years ago

Hi,

In message "Re: [ruby-core:41950] [ruby-trunk - Feature #5856][Open] Feature: Raise any object"
on Sat, 7 Jan 2012 06:51:53 +0900, Kurt Stephens 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.

Updated by nobu (Nobuyoshi Nakada) about 12 years ago

  • Category set to core
  • Status changed from Open to Feedback
  • Assignee set to matz (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

Updated by matz (Yukihiro Matsumoto) about 12 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.

Updated by kstephens (Kurt Stephens) about 12 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.

Updated by mame (Yusuke Endoh) over 11 years ago

  • Target version set to 2.6

Updated by matz (Yukihiro Matsumoto) over 11 years 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.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0