Exception: Axn::Failure
- Inherits:
-
StandardError
- Object
- StandardError
- Axn::Failure
- Defined in:
- lib/axn/exceptions.rb
Overview
Raised when fail! is called
Constant Summary collapse
- DEFAULT_MESSAGE =
"Execution was halted"
Instance Attribute Summary collapse
-
#__originating_action ⇒ Object
readonly
The action whose
fail!raised this. -
#raw_reason ⇒ Object
readonly
The action whose
fail!raised this.
Instance Method Summary collapse
-
#__present_as(string) ⇒ Object
Set the resolved, presentation-layer string shown by #message.
-
#default_message? ⇒ Boolean
Keyed off the RAW reason, not #message: once __present_as stamps the resolved presentation, #message no longer reflects whether the caller supplied a reason.
-
#initialize(message = nil, standalone: false, action: nil) ⇒ Failure
constructor
A new instance of Failure.
- #inspect ⇒ Object
- #message ⇒ Object
- #standalone? ⇒ Boolean
-
#supplied_reason ⇒ Object
The reason the caller handed
fail!, or nil when they handed none — the undispatched form ofraw_reason.presence.
Constructor Details
#initialize(message = nil, standalone: false, action: nil) ⇒ Failure
Returns a new instance of Failure.
111 112 113 114 115 116 117 |
# File 'lib/axn/exceptions.rb', line 111 def initialize( = nil, standalone: false, action: nil) @raw_reason = @presentation = nil @standalone = standalone @__originating_action = action super() end |
Instance Attribute Details
#__originating_action ⇒ Object (readonly)
The action whose fail! raised this. We hold the action OBJECT (compared by identity in
Result#_fail_standalone?), not its object_id — consistent with ExceptionClassification's
identity keying, which deliberately avoids the freed-then-reused-object_id collision hazard.
standalone: is scoped to that action: an ancestor that catches a bubbled child Failure still
applies its OWN base (the child's opt-out is local).
NOTE: this pins the action (and its context/inputs) for the Failure's lifetime — only relevant
if a bare result.exception is retained beyond its result; results are normally short-lived.
109 110 111 |
# File 'lib/axn/exceptions.rb', line 109 def __originating_action @__originating_action end |
#raw_reason ⇒ Object (readonly)
The action whose fail! raised this. We hold the action OBJECT (compared by identity in
Result#_fail_standalone?), not its object_id — consistent with ExceptionClassification's
identity keying, which deliberately avoids the freed-then-reused-object_id collision hazard.
standalone: is scoped to that action: an ancestor that catches a bubbled child Failure still
applies its OWN base (the child's opt-out is local).
NOTE: this pins the action (and its context/inputs) for the Failure's lifetime — only relevant
if a bare result.exception is retained beyond its result; results are normally short-lived.
109 110 111 |
# File 'lib/axn/exceptions.rb', line 109 def raw_reason @raw_reason end |
Instance Method Details
#__present_as(string) ⇒ Object
Set the resolved, presentation-layer string shown by #message. Leaves raw_reason untouched so the framework can keep re-resolving from the raw reason without double-prefixing.
Normalized on assignment, undispatched, and read back plain — because what resolution produces is
ultimately the caller's own object when they passed one (fail!(obj) with no declared base error
resolves to obj itself). presence here dispatched that object's blank? from inside the settling
path, which aborted _settle_exception! mid-way: the on_error callbacks and the failure
classification below it never ran, and the executor's guard warned about a reporting failure instead.
127 |
# File 'lib/axn/exceptions.rb', line 127 def __present_as(string) = @presentation = Axn::Internal::NativeMethods.absent_value?(string) ? nil : string |
#default_message? ⇒ Boolean
Keyed off the RAW reason, not #message: once __present_as stamps the resolved presentation, #message no longer reflects whether the caller supplied a reason. Post-run consumers read this on a finalized, stamped result (e.g. ContextFacadeInspector#status → "[failed]" vs "[failed with…]").
The comparison runs on axn's OWN frozen String as receiver rather than on the reason, so no == the
caller's object defines decides this either. String#eql? is value equality for a String (subclass
included) and false for anything else, which is what a reason equal to the default message needs.
155 156 157 158 |
# File 'lib/axn/exceptions.rb', line 155 def reason = supplied_reason Axn::Internal::Identity.nil_value?(reason) || DEFAULT_MESSAGE.eql?(reason) end |
#inspect ⇒ Object
160 |
# File 'lib/axn/exceptions.rb', line 160 def inspect = "#<#{self.class.name} '#{}'>" |
#message ⇒ Object
146 |
# File 'lib/axn/exceptions.rb', line 146 def = @presentation || supplied_reason || DEFAULT_MESSAGE |
#standalone? ⇒ Boolean
129 |
# File 'lib/axn/exceptions.rb', line 129 def standalone? = @standalone |
#supplied_reason ⇒ Object
The reason the caller handed fail!, or nil when they handed none — the undispatched form of
raw_reason.presence.
fail! takes an ARBITRARY object, and this is read while a failure is already being reported: from
#message, from #inspect, and from Result#_user_provided_error_message, which is what result.error
and result.message resolve through. So presence meant dispatching the caller's blank?/empty? from
inside axn's own reporting, where an override that raises replaces the failure being reported with its own
exception — and outside StandardError it escapes the rescue meant to settle it. fail! with an object
whose blank? raises took down result.error, result.message and result.inspect alike, with the
failure itself intact underneath.
The spellings that mean "no reason" are decided from the value's class and its own bytes instead
(NativeMethods.absent_value?), which is the same undispatched answer a declared name gets.
144 |
# File 'lib/axn/exceptions.rb', line 144 def supplied_reason = Axn::Internal::NativeMethods.absent_value?(@raw_reason) ? nil : @raw_reason |