Class: CMDx::Errors

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/cmdx/errors.rb

Overview

Per-task container of validation / coercion / output errors. Each key maps to a deduplicating Set of messages. A non-empty Errors forces Runtime to throw a failed signal (‘signal_errors!`). Frozen on teardown by Runtime.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeErrors

Returns a new instance of Errors.



13
14
15
# File 'lib/cmdx/errors.rb', line 13

def initialize
  @messages = {}
end

Instance Attribute Details

#messagesObject (readonly)

Returns the value of attribute messages.



11
12
13
# File 'lib/cmdx/errors.rb', line 11

def messages
  @messages
end

Instance Method Details

#[](key) ⇒ Array<String>

Returns messages for ‘key`, or a frozen empty array.

Parameters:

  • key (Symbol)

Returns:

  • (Array<String>)

    messages for ‘key`, or a frozen empty array



45
46
47
# File 'lib/cmdx/errors.rb', line 45

def [](key)
  messages[key]&.to_a || EMPTY_ARRAY
end

#add(key, message) ⇒ Set<String> Also known as: []=

Adds ‘message` under `key`. Duplicate messages are silently dropped.

Parameters:

  • key (Symbol)
  • message (String)

Returns:

  • (Set<String>)

    the set of messages now stored under ‘key`



22
23
24
# File 'lib/cmdx/errors.rb', line 22

def add(key, message)
  (messages[key] ||= Set.new) << message
end

#added?(key, message) ⇒ Boolean

Returns true when ‘message` is recorded under `key`.

Parameters:

  • key (Symbol)
  • message (String)

Returns:

  • (Boolean)

    true when ‘message` is recorded under `key`



52
53
54
# File 'lib/cmdx/errors.rb', line 52

def added?(key, message)
  !!messages[key]&.include?(message)
end

#as_jsonHash{Symbol => Array<String>}

JSON-friendly hash view. Aliases #to_h for conventional ‘as_json` callers (e.g. Rails).

Returns:

  • (Hash{Symbol => Array<String>})


135
136
137
# File 'lib/cmdx/errors.rb', line 135

def as_json(*)
  to_h
end

#clearHash{Symbol => Set<String>}

Returns empties the container.

Returns:

  • (Hash{Symbol => Set<String>})

    empties the container



108
109
110
# File 'lib/cmdx/errors.rb', line 108

def clear
  messages.clear
end

#countInteger

Returns total messages across all keys.

Returns:

  • (Integer)

    total messages across all keys



79
80
81
# File 'lib/cmdx/errors.rb', line 79

def count
  messages.each_value.sum(&:size)
end

#deconstructArray<Array(Symbol, Array<String>)>

Pattern-matching support for ‘case errors in […]`.

Returns:

  • (Array<Array(Symbol, Array<String>)>)


170
171
172
# File 'lib/cmdx/errors.rb', line 170

def deconstruct
  to_h.to_a
end

#deconstruct_keys(keys) ⇒ Hash{Symbol => Array<String>}

Pattern-matching support for ‘case errors in …`.

Examples:

case task.errors
in { name: [_, *] } then handle_name_errors(task)
end

Parameters:

  • keys (Array<Symbol>, nil)

    restrict the returned hash to these keys

Returns:

  • (Hash{Symbol => Array<String>})


163
164
165
# File 'lib/cmdx/errors.rb', line 163

def deconstruct_keys(keys)
  keys.nil? ? to_h : to_h.slice(*keys)
end

#delete(key) ⇒ Set<String>?

Returns the removed set, or nil when absent.

Parameters:

  • key (Symbol)

Returns:

  • (Set<String>, nil)

    the removed set, or nil when absent



103
104
105
# File 'lib/cmdx/errors.rb', line 103

def delete(key)
  messages.delete(key)
end

#each {|key, set| ... } ⇒ Errors, Enumerator

Yields:

  • (key, set)

    each ‘[key, Set<String>]` pair

Returns:



85
86
87
# File 'lib/cmdx/errors.rb', line 85

def each(&)
  messages.each(&)
end

#each_key {|Symbol| ... } ⇒ Errors, Enumerator

Yields:

  • (Symbol)

Returns:



91
92
93
# File 'lib/cmdx/errors.rb', line 91

def each_key(&)
  messages.each_key(&)
end

#each_value {|Set<String>| ... } ⇒ Errors, Enumerator

Yields:

  • (Set<String>)

Returns:



97
98
99
# File 'lib/cmdx/errors.rb', line 97

def each_value(&)
  messages.each_value(&)
end

#empty?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/cmdx/errors.rb', line 69

def empty?
  messages.empty?
end

#freezeErrors

Freezes the container and every message set. Called by Runtime teardown.

Returns:



177
178
179
180
# File 'lib/cmdx/errors.rb', line 177

def freeze
  messages.each_value(&:freeze).freeze
  super
end

#full_messagesHash{Symbol => Array<String>}

Returns messages prefixed with their key (e.g. ‘{ name: [“name is required”] }`).

Returns:

  • (Hash{Symbol => Array<String>})

    messages prefixed with their key (e.g. ‘{ name: [“name is required”] }`)



114
115
116
117
118
# File 'lib/cmdx/errors.rb', line 114

def full_messages
  messages.each_with_object({}) do |(key, set), hash|
    hash[key] = set.map { |message| "#{key} #{message}" }
  end
end

#key?(key) ⇒ Boolean Also known as: for?

Parameters:

  • key (Symbol)

Returns:

  • (Boolean)


58
59
60
# File 'lib/cmdx/errors.rb', line 58

def key?(key)
  messages.key?(key)
end

#keysArray<Symbol>

Returns keys with at least one message.

Returns:

  • (Array<Symbol>)

    keys with at least one message



64
65
66
# File 'lib/cmdx/errors.rb', line 64

def keys
  messages.keys
end

#merge!(other) ⇒ void

This method returns an undefined value.

Copies every message from ‘other` into self. Existing messages are preserved and duplicates (same key + message) are silently dropped by the underlying Set. Accepts any object that responds to `#to_hash` returning `Hash=> Enumerable<String>` — typically another CMDx::Errors instance.

Examples:

Combine validation errors from a nested task

parent.errors.merge!(child.result.errors)

Parameters:



37
38
39
40
41
# File 'lib/cmdx/errors.rb', line 37

def merge!(other)
  other.to_hash.each do |key, messages|
    messages.each { |message| add(key, message) }
  end
end

#sizeInteger

Returns number of keyed entries.

Returns:

  • (Integer)

    number of keyed entries



74
75
76
# File 'lib/cmdx/errors.rb', line 74

def size
  messages.size
end

#to_hHash{Symbol => Array<String>}

Returns raw messages as arrays.

Returns:

  • (Hash{Symbol => Array<String>})

    raw messages as arrays



121
122
123
# File 'lib/cmdx/errors.rb', line 121

def to_h
  messages.transform_values(&:to_a)
end

#to_hash(full = false) ⇒ Hash{Symbol => Array<String>}

Parameters:

Returns:

  • (Hash{Symbol => Array<String>})


127
128
129
# File 'lib/cmdx/errors.rb', line 127

def to_hash(full = false)
  full ? full_messages : to_h
end

#to_json(*args) ⇒ String

Serializes the error messages to a JSON string. Symbol keys are emitted as strings by the ‘json` stdlib.

Parameters:

  • args (Array)

    forwarded to ‘Hash#to_json`

Returns:

  • (String)


144
145
146
# File 'lib/cmdx/errors.rb', line 144

def to_json(*args)
  to_h.to_json(*args)
end

#to_sString

Returns all full messages joined with ‘“. ”`, suitable as a fail reason.

Returns:

  • (String)

    all full messages joined with ‘“. ”`, suitable as a fail reason



150
151
152
# File 'lib/cmdx/errors.rb', line 150

def to_s
  full_messages.values.flatten.join(". ")
end