File: wrapexception.rb

package info (click to toggle)
ruby-oj 3.16.12-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 14,192 kB
  • sloc: ansic: 19,659; ruby: 11,750; sh: 70; makefile: 17
file content (57 lines) | stat: -rwxr-xr-x 2,426 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env ruby
# frozen_string_literal: true

# Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is
# required. That can be set in the RUBYOPT environment variable.
# export RUBYOPT=-w

$VERBOSE = true

# $LOAD_PATH << File.join(File.dirname(__FILE__), "../lib")
# $LOAD_PATH << File.join(File.dirname(__FILE__), "../ext")

require 'oj'

# Oj is not able to automatically deserialize all classes that are a subclass of
# a Ruby Exception. Only exception that take one required string argument in the
# initialize() method are supported. This is an example of how to write an
# Exception subclass that supports both a single string initializer and an
# Exception as an argument. Additional optional arguments can be added as well.
#
# The reason for this restriction has to do with a design decision on the part
# of the Ruby developers. Exceptions are special Objects. They do not follow the
# rules of other Objects. Exceptions have 'mesg' and a 'bt' attribute. Note that
# these are not '@mesg' and '@bt'. They can not be set using the normal C or
# Ruby calls. The only way I have found to set the 'mesg' attribute is through
# the initializer. Unfortunately that means any subclass that provides a
# different initializer can not be automatically decoded. A way around this is
# to use a create function but this example shows an alternative.
class WrapException < StandardError
  attr_reader :original

  def initialize(msg_or_err)
    if msg_or_err.is_a?(Exception)
      super(msg_or_err.message)
      @original = msg_or_err
      set_backtrace(msg_or_err.backtrace)
    else
      super(message)
      @original = nil
    end
  end
end

e = WrapException.new(RuntimeError.new('Something broke.'))

json = Oj.dump(e, :mode => :object)
puts "original:\n#{json}"
# outputs:
# original:
# {"^o":"WrapException","original":{"^o":"RuntimeError","~mesg":"Something broke.","~bt":null},"~mesg":"Something broke.","~bt":null}

e2 = Oj.load(json, :mode => :object)
puts "dumped, loaded, and dumped again:\n#{Oj.dump(e2, :mode => :object)}"
# outputs:
# original: {"^o":"WrapException","original":{"^o":"RuntimeError","~mesg":"Something broke.","~bt":null},"~mesg":"Something broke.","~bt":null}
# dumped, loaded, and dumped again:
# {"^o":"WrapException","original":{"^o":"RuntimeError","~mesg":"Something broke.","~bt":null},"~mesg":"Something broke.","~bt":null}