diff options
author | sorah <sorah@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-12-12 11:47:16 +0000 |
---|---|---|
committer | sorah <sorah@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-12-12 11:47:16 +0000 |
commit | 0d7718896cfb629ad823b9ca5004465ef2063ab8 () | |
tree | 764655a01a2038af09ef45f4ae5fbeb0ff31ce42 | |
parent | 838f23ae34a634f3bbe39d27b861abc8dd853762 (diff) |
error.c(exc_full_message): Exception#full_message
Add a method to retrieve a String expression of an exception, formatted in the same way that Ruby prints an uncaught exception out. [Feature #14141] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61154 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | error.c | 20 | ||||
-rw-r--r-- | eval_error.c | 127 | ||||
-rw-r--r-- | test/ruby/test_exception.rb | 11 |
4 files changed, 109 insertions, 53 deletions
@@ -31,6 +31,10 @@ with all sufficient information, see the ChangeLog file or Redmine * Now deprecated [Feature #3072] * Dir * Dir.glob provides new optional keyword argument, :base. @@ -923,6 +923,25 @@ exc_to_s(VALUE exc) /* * call-seq: * exception.message -> string * * Returns the result of invoking <code>exception.to_s</code>. @@ -2189,6 +2208,7 @@ Init_Exception(void) rb_define_method(rb_eException, "==", exc_equal, 1); rb_define_method(rb_eException, "to_s", exc_to_s, 0); rb_define_method(rb_eException, "message", exc_message, 0); rb_define_method(rb_eException, "inspect", exc_inspect, 0); rb_define_method(rb_eException, "backtrace", exc_backtrace, 0); rb_define_method(rb_eException, "backtrace_locations", exc_backtrace_locations, 0); @@ -4,25 +4,38 @@ */ #ifdef HAVE_BUILTIN___BUILTIN_CONSTANT_P #define warn_print(x) RB_GNUC_EXTENSION_BLOCK( \ (__builtin_constant_p(x)) ? \ rb_write_error2((x), (long)strlen(x)) : \ rb_write_error(x) \ ) #else #define warn_print(x) rb_write_error(x) #endif #define warn_print2(x,l) rb_write_error2((x),(l)) #define warn_print_str(x) rb_write_error_str(x) static VALUE error_pos_str(void); static void -error_pos(void) { - VALUE str = error_pos_str(); - if (!NIL_P(str)) { - warn_print_str(str); } } @@ -73,7 +86,7 @@ error_print(rb_execution_context_t *ec) } static void -print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg, int colored) { static const char underline[] = "\033[4;1m"; static const char bold[] = "\033[1m"; @@ -85,14 +98,14 @@ print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg, int colo if (emesg != Qundef) { if (NIL_P(errat) || RARRAY_LEN(errat) == 0 || NIL_P(mesg = RARRAY_AREF(errat, 0))) { - error_pos(); } else { - warn_print_str(mesg); - warn_print(": "); } - if (colored) warn_print(bold); if (!NIL_P(emesg)) { einfo = RSTRING_PTR(emesg); @@ -101,17 +114,17 @@ print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg, int colo } if (eclass == rb_eRuntimeError && elen == 0) { - if (colored) warn_print(underline); - warn_print("unhandled exception\n"); } else { VALUE epath; epath = rb_class_name(eclass); if (elen == 0) { - if (colored) warn_print(underline); - warn_print_str(epath); - warn_print("\n"); } else { const char *tail = 0; @@ -123,26 +136,26 @@ print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg, int colo len = tail - einfo; tail++; /* skip newline */ } - warn_print_str(tail ? rb_str_subseq(emesg, 0, len) : emesg); if (epath) { - warn_print(" ("); - if (colored) warn_print(underline); - warn_print_str(epath); - if (colored) warn_print(reset); - if (colored) warn_print(bold); - warn_print(")\n"); } if (tail) { - warn_print_str(rb_str_subseq(emesg, tail - einfo, elen - len - 1)); } - if (tail ? einfo[elen-1] != '\n' : !epath) warn_print2("\n", 1); } } - if (colored) warn_print(reset); } static void -print_backtrace(const VALUE eclass, const VALUE errat, int reverse) { if (!NIL_P(errat)) { long i; @@ -161,12 +174,12 @@ print_backtrace(const VALUE eclass, const VALUE errat, int reverse) for (i = 1; i < len; i++) { VALUE line = RARRAY_AREF(errat, reverse ? len - i : i); if (RB_TYPE_P(line, T_STRING)) { - VALUE str = rb_str_new_cstr("\t"); - if (reverse) rb_str_catf(str, "%*ld: ", width, len - i); - warn_print_str(rb_str_catf(str, "from %"PRIsVALUE"\n", line)); } if (skip && i == TRACE_HEAD && len > TRACE_MAX) { - warn_print_str(rb_sprintf("\t ... %ld levels...\n", len - TRACE_HEAD - TRACE_TAIL)); i = len - TRACE_TAIL; } @@ -175,26 +188,16 @@ print_backtrace(const VALUE eclass, const VALUE errat, int reverse) } void -rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo) { - volatile VALUE errat = Qundef; - volatile int raised_flag = ec->raised_flag; volatile VALUE eclass = Qundef, emesg = Qundef; if (NIL_P(errinfo)) return; - rb_ec_raised_clear(ec); - EC_PUSH_TAG(ec); - if (EC_EXEC_TAG() == TAG_NONE) { - errat = rb_get_backtrace(errinfo); - } - else if (errat == Qundef) { errat = Qnil; } - else if (eclass == Qundef || emesg != Qundef) { - goto error; - } if ((eclass = CLASS_OF(errinfo)) != Qundef) { VALUE e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0); if (e != Qundef) { @@ -203,15 +206,33 @@ rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo) } } if (rb_stderr_tty_p()) { - warn_print("\033[1mTraceback \033[m(most recent call last):\n"); - print_backtrace(eclass, errat, TRUE); - print_errinfo(eclass, errat, emesg, TRUE); } else { - print_errinfo(eclass, errat, emesg, FALSE); - print_backtrace(eclass, errat, FALSE); } - error: EC_POP_TAG(); ec->errinfo = errinfo; rb_ec_raised_set(ec, raised_flag); @@ -290,28 +311,28 @@ error_handle(int ex) break; case TAG_RETURN: - error_pos(); warn_print("unexpected return\n"); break; case TAG_NEXT: - error_pos(); warn_print("unexpected next\n"); break; case TAG_BREAK: - error_pos(); warn_print("unexpected break\n"); break; case TAG_REDO: - error_pos(); warn_print("unexpected redo\n"); break; case TAG_RETRY: - error_pos(); warn_print("retry outside of rescue clause\n"); break; case TAG_THROW: /* TODO: fix me */ - error_pos(); warn_print("unexpected throw\n"); break; case TAG_RAISE: { @@ -1094,4 +1094,15 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status| } end; end end |