1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

eval.c: refactor exception cause

* eval.c (setup_exception): set up cause after exception to be raised
  is fixed.  [Feature #8257]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43684 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2013-11-15 14:08:49 +00:00
parent e7d29c6cda
commit 549b35c1dc
2 changed files with 45 additions and 7 deletions

35
eval.c
View file

@ -431,6 +431,34 @@ rb_frozen_class_p(VALUE klass)
}
NORETURN(static void rb_longjmp(int, volatile VALUE));
static VALUE get_errinfo(void);
static VALUE get_thread_errinfo(rb_thread_t *th);
static VALUE
exc_setup_cause(VALUE exc, VALUE cause)
{
ID id_cause;
CONST_ID(id_cause, "cause");
#if SUPPORT_JOKE
if (NIL_P(cause)) {
ID id_true_cause;
CONST_ID(id_true_cause, "true_cause");
cause = rb_attr_get(rb_eFatal, id_true_cause);
if (NIL_P(cause)) {
cause = rb_exc_new_cstr(rb_eFatal, "because using such Ruby");
rb_ivar_set(cause, id_cause, INT2FIX(42)); /* the answer */
OBJ_FREEZE(cause);
rb_ivar_set(rb_eFatal, id_true_cause, cause);
}
}
#endif
if (!NIL_P(cause) && cause != exc) {
rb_ivar_set(exc, id_cause, cause);
}
return exc;
}
static void
setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg)
@ -447,6 +475,7 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg)
if (NIL_P(mesg)) {
mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
}
exc_setup_cause(mesg, get_thread_errinfo(th));
file = rb_sourcefile();
if (file) line = rb_sourceline();
@ -552,8 +581,6 @@ rb_interrupt(void)
rb_raise(rb_eInterrupt, "%s", "");
}
static VALUE get_errinfo(void);
/*
* call-seq:
* raise
@ -641,10 +668,6 @@ make_exception(int argc, VALUE *argv, int isstr)
if (argc > 2)
set_backtrace(mesg, argv[2]);
}
{
VALUE cause = get_errinfo();
if (!NIL_P(cause)) rb_iv_set(mesg, "cause", cause);
}
return mesg;
}

View file

@ -479,16 +479,31 @@ end.join
def test_cause
msg = "[Feature #8257]"
cause = nil
e = assert_raise(StandardError) {
begin
raise msg
rescue => e
assert_nil(e.cause, msg)
cause = e.cause
raise StandardError
end
}
assert_nil(cause, msg)
cause = e.cause
assert_instance_of(RuntimeError, cause, msg)
assert_equal(msg, cause.message, msg)
end
def test_cause_reraised
msg = "[Feature #8257]"
cause = nil
e = assert_raise(RuntimeError) {
begin
raise msg
rescue => e
raise e
end
}
assert_not_same(e, e.cause, "#{msg}: should not be recursive")
end
end