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:
parent
e7d29c6cda
commit
549b35c1dc
2 changed files with 45 additions and 7 deletions
35
eval.c
35
eval.c
|
@ -431,6 +431,34 @@ rb_frozen_class_p(VALUE klass)
|
||||||
}
|
}
|
||||||
|
|
||||||
NORETURN(static void rb_longjmp(int, volatile VALUE));
|
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
|
static void
|
||||||
setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg)
|
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)) {
|
if (NIL_P(mesg)) {
|
||||||
mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
|
mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
|
||||||
}
|
}
|
||||||
|
exc_setup_cause(mesg, get_thread_errinfo(th));
|
||||||
|
|
||||||
file = rb_sourcefile();
|
file = rb_sourcefile();
|
||||||
if (file) line = rb_sourceline();
|
if (file) line = rb_sourceline();
|
||||||
|
@ -552,8 +581,6 @@ rb_interrupt(void)
|
||||||
rb_raise(rb_eInterrupt, "%s", "");
|
rb_raise(rb_eInterrupt, "%s", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE get_errinfo(void);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* raise
|
* raise
|
||||||
|
@ -641,10 +668,6 @@ make_exception(int argc, VALUE *argv, int isstr)
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
set_backtrace(mesg, argv[2]);
|
set_backtrace(mesg, argv[2]);
|
||||||
}
|
}
|
||||||
{
|
|
||||||
VALUE cause = get_errinfo();
|
|
||||||
if (!NIL_P(cause)) rb_iv_set(mesg, "cause", cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mesg;
|
return mesg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -479,16 +479,31 @@ end.join
|
||||||
|
|
||||||
def test_cause
|
def test_cause
|
||||||
msg = "[Feature #8257]"
|
msg = "[Feature #8257]"
|
||||||
|
cause = nil
|
||||||
e = assert_raise(StandardError) {
|
e = assert_raise(StandardError) {
|
||||||
begin
|
begin
|
||||||
raise msg
|
raise msg
|
||||||
rescue => e
|
rescue => e
|
||||||
assert_nil(e.cause, msg)
|
cause = e.cause
|
||||||
raise StandardError
|
raise StandardError
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
assert_nil(cause, msg)
|
||||||
cause = e.cause
|
cause = e.cause
|
||||||
assert_instance_of(RuntimeError, cause, msg)
|
assert_instance_of(RuntimeError, cause, msg)
|
||||||
assert_equal(msg, cause.message, msg)
|
assert_equal(msg, cause.message, msg)
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Reference in a new issue