Class: Decoding::Failure

Inherits:
Object
  • Object
show all
Defined in:
lib/decoding/failure.rb

Overview

A failure is an error message, much like a string, but with an added stack of earlier messages.

This is useful to create clearer error messages when using compound decoders, such as array(string). If the string decoder fails with an error, the array decoder can push 3 to the stack to indicate that happened at index 3 in its input value.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(msg, path = []) ⇒ Failure

Returns a new instance of Failure.

Parameters:

  • (defaults to: [])

    Internal parameter for creating copies with updated paths



25
26
27
28
29
# File 'lib/decoding/failure.rb', line 25

def initialize(msg, path = [])
  @msg = msg
  @path = path.dup.freeze
  freeze
end

Instance Attribute Details

#msg ⇒ String (readonly)

The error message, without the location it occurred at.

Returns:



15
16
17
# File 'lib/decoding/failure.rb', line 15

def msg
  @msg
end

#path ⇒ Array (readonly)

The stack of segments describing where the error occurred, innermost first.

Returns:



21
22
23
# File 'lib/decoding/failure.rb', line 21

def path
  @path
end

Instance Method Details

#combine(others) {|messages| ... } ⇒ Decoding::Failure

Combine this failure with others into a single failure, using the given block to build a single message from all of their messages.

When all failures occurred at the same location, that location is kept for the combined failure and left out of the individual messages, since the combined failure already describes it. Otherwise each message describes its own location.

Parameters:

Yield Parameters:

  • messages (Array<String>)

Yield Returns:

  • (String)

Returns:



71
72
73
74
75
76
# File 'lib/decoding/failure.rb', line 71

def combine(others)
  failures = [self, *others]
  return self.class.new(yield(failures.map(&:to_s))) unless failures.map(&:path).uniq.size == 1

  self.class.new(yield(failures.map(&:msg)), @path)
end

#eql?(other) ⇒ Boolean Also known as: ==

Returns:



31
32
33
34
35
# File 'lib/decoding/failure.rb', line 31

def eql?(other)
  other.is_a?(self.class) &&
    msg == other.msg &&
    path == other.path
end

#map {|msg| ... } ⇒ Decoding::Failure

Create a copy of this failure with a transformed error message, retaining the current stack of errors.

This is useful for decoders that want to replace the error message of a nested decoder with something more fitting, without losing the location of the error.

Yield Parameters:

  • msg (String)

Yield Returns:

  • (String)

Returns:



57
# File 'lib/decoding/failure.rb', line 57

def map = self.class.new(yield(@msg), @path)

#push(segment) ⇒ Decoding::Failure

Add segments to the stack of errors. Returns a new Failure instance with the updated path.

Parameters:

Returns:



43
44
45
# File 'lib/decoding/failure.rb', line 43

def push(segment)
  self.class.new(@msg, @path + [segment])
end

#to_s ⇒ Object



78
79
80
81
82
83
84
# File 'lib/decoding/failure.rb', line 78

def to_s
  if @path.any?
    "Error at .#{@path.reverse.join(".")}: #{@msg}"
  else
    @msg
  end
end