diff options
author | Aaron Patterson <tenderlove@github.com> | 2019-01-09 13:53:48 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-09 13:53:48 -0800 |
commit | 63c94cf4f1a877a84c9bbed2ccabc773f9e56035 (patch) | |
tree | 36540abdd3e1e6286f6da14b4674e91c939d93f3 | |
parent | 8eb0be0d8dfc8d25facb0db078d9c90d753c6c82 (diff) | |
parent | e07a9d845410db939c22d357fdcebca5a7b00006 (diff) | |
download | psych-63c94cf4f1a877a84c9bbed2ccabc773f9e56035.zip |
Merge pull request #382 from ruby/exception-handling-refactor
Exception backtraces should round trip
-rw-r--r-- | lib/psych/visitors/to_ruby.rb | 2 | ||||
-rw-r--r-- | lib/psych/visitors/yaml_tree.rb | 52 | ||||
-rw-r--r-- | test/psych/test_exception.rb | 14 |
3 files changed, 36 insertions, 32 deletions
diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb index 74a52df..c265acb 100644 --- a/lib/psych/visitors/to_ruby.rb +++ b/lib/psych/visitors/to_ruby.rb @@ -252,6 +252,8 @@ module Psych e = build_exception((resolve_class($1) || class_loader.exception), h.delete('message')) + + e.set_backtrace h.delete('backtrace') if h.key? 'backtrace' init_with(e, h, o) when '!set', 'tag:yaml.org,2002:set' diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb index cfed8f1..62d1d5c 100644 --- a/lib/psych/visitors/yaml_tree.rb +++ b/lib/psych/visitors/yaml_tree.rb @@ -181,41 +181,11 @@ module Psych end def visit_Exception o - tag = ['!ruby/exception', o.class.name].join ':' - - @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK - - { - 'message' => private_iv_get(o, 'mesg'), - 'backtrace' => private_iv_get(o, 'backtrace'), - }.each do |k,v| - next unless v - @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY - accept v - end - - dump_ivars o - - @emitter.end_mapping + dump_exception o, private_iv_get(o, 'mesg') end def visit_NameError o - tag = ['!ruby/exception', o.class.name].join ':' - - @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK - - { - 'message' => o.message.to_s, - 'backtrace' => private_iv_get(o, 'backtrace'), - }.each do |k,v| - next unless v - @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY - accept v - end - - dump_ivars o - - @emitter.end_mapping + dump_exception o, o.message.to_s end def visit_Regexp o @@ -492,6 +462,24 @@ module Psych def dump_list o end + def dump_exception o, msg + tag = ['!ruby/exception', o.class.name].join ':' + + @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK + + if msg + @emitter.scalar 'message', nil, nil, true, false, Nodes::Scalar::ANY + accept msg + end + + @emitter.scalar 'backtrace', nil, nil, true, false, Nodes::Scalar::ANY + accept o.backtrace + + dump_ivars o + + @emitter.end_mapping + end + def format_time time if time.utc? time.strftime("%Y-%m-%d %H:%M:%S.%9N Z") diff --git a/test/psych/test_exception.rb b/test/psych/test_exception.rb index df7fd73..e7fc88c 100644 --- a/test/psych/test_exception.rb +++ b/test/psych/test_exception.rb @@ -23,6 +23,20 @@ module Psych $VERBOSE = @orig_verbose end + def make_ex msg = 'oh no!' + begin + raise msg + rescue ::Exception => e + e + end + end + + def test_backtrace + err = make_ex + new_err = Psych.load(Psych.dump(err)) + assert_equal err.backtrace, new_err.backtrace + end + def test_naming_exception err = String.xxx rescue $! new_err = Psych.load(Psych.dump(err)) |