Exception: Ruptr::SurrogateException

Inherits:
Exception
  • Object
show all
Defined in:
lib/ruptr/surrogate_exception.rb

Overview

Exception that copy some of the information of another original exception in a way that (hopefully) can be safely marshalled.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(message = nil, detailed_message: nil, highlighted_detailed_message: nil, original_class_name: nil, backtrace: nil) ⇒ SurrogateException

Returns a new instance of SurrogateException.



52
53
54
55
56
57
58
59
60
61
# File 'lib/ruptr/surrogate_exception.rb', line 52

def initialize(message = nil,
               detailed_message: nil, highlighted_detailed_message: nil,
               original_class_name: nil,
               backtrace: nil)
  super(safe_string(message))
  @detailed_message = safe_string(detailed_message)
  @highlighted_detailed_message = safe_string(highlighted_detailed_message)
  set_backtrace(backtrace)
  @original_class_name = safe_string(original_class_name)
end

Instance Attribute Details

#original_class_nameObject (readonly)

Returns the value of attribute original_class_name.



63
64
65
# File 'lib/ruptr/surrogate_exception.rb', line 63

def original_class_name
  @original_class_name
end

Class Method Details

.detailed_message_supported?Boolean

Returns:

  • (Boolean)


7
# File 'lib/ruptr/surrogate_exception.rb', line 7

def self.detailed_message_supported? = Exception.method_defined?(:detailed_message)

.from(original_exception) ⇒ Object



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
# File 'lib/ruptr/surrogate_exception.rb', line 23

def self.from(original_exception)
  return from_1(original_exception) unless original_exception.cause
  # Recreate the cause exception chain by raising the surrogate exceptions.  Simply redefining
  # the #cause method does not work in CRuby (apparently the cause is stored in a special
  # instance variable that is then accessed directly).
  rec = lambda do |ex|
    if ex.cause
      if ex.cause.cause
        begin
          rec.call(ex.cause)
        rescue self
          raise from_1(ex)
        end
      else
        raise from_1(ex), cause: from_1(ex.cause)
      end
    else
      raise from_1(ex), cause: nil # don't use implicit $!, if any
    end
  end
  begin
    rec.call(original_exception)
  rescue self
    $!
  end
end

.from_1(original_exception) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/ruptr/surrogate_exception.rb', line 9

def self.from_1(original_exception)
  new(original_exception.message,
      **if detailed_message_supported?
          {
            detailed_message: original_exception.detailed_message(highlight: false),
            highlighted_detailed_message: original_exception.detailed_message(highlight: true),
          }
        else
          {}
        end,
      original_class_name: original_exception.class.name,
      backtrace: original_exception.backtrace)
end

Instance Method Details

#detailed_message(highlight: false, **_) ⇒ Object



66
67
68
# File 'lib/ruptr/surrogate_exception.rb', line 66

def detailed_message(highlight: false, **_)
  (highlight ? @highlighted_detailed_message || @detailed_message : @detailed_message) || super
end