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, String)

Returns:

  • (Array<String>)

    messages for ‘key`, or a frozen empty array



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

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

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

Adds ‘message` under `key`. Duplicate messages are silently dropped. `key` is coerced to a Symbol to match Context’s key normalization.

Parameters:

  • key (Symbol, String)
  • message (String)

Returns:

  • (Set<String>)

    the set of messages now stored under ‘key`



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

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

#added?(key, message) ⇒ Boolean

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

Parameters:

  • key (Symbol, String)
  • message (String)

Returns:

  • (Boolean)

    true when ‘message` is recorded under `key`



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

def added?(key, message)
  !!messages[key.to_sym]&.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>})


139
140
141
# File 'lib/cmdx/errors.rb', line 139

def as_json(*)
  to_h
end

#clearHash{Symbol => Set<String>}

Returns empties the container.

Returns:

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

    empties the container



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

def clear
  messages.clear
end

#countInteger

Returns total messages across all keys.

Returns:

  • (Integer)

    total messages across all keys



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

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>)>)


174
175
176
# File 'lib/cmdx/errors.rb', line 174

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>})


167
168
169
# File 'lib/cmdx/errors.rb', line 167

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, String)

Returns:

  • (Set<String>, nil)

    the removed set, or nil when absent



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

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

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

Yields:

  • (key, set)

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

Returns:



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

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

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

Yields:

  • (Symbol)

Returns:



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

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

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

Yields:

  • (Set<String>)

Returns:



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

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

#empty?Boolean

Returns:

  • (Boolean)


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

def empty?
  messages.empty?
end

#freezeErrors

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

Returns:



181
182
183
184
# File 'lib/cmdx/errors.rb', line 181

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”] }`)



115
116
117
118
119
120
121
122
# File 'lib/cmdx/errors.rb', line 115

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

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

Parameters:

  • key (Symbol, String)

Returns:

  • (Boolean)


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

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

#keysArray<Symbol>

Returns keys with at least one message.

Returns:

  • (Array<Symbol>)

    keys with at least one message



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

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:



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

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



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

def size
  messages.size
end

#to_hHash{Symbol => Array<String>}

Returns raw messages as arrays.

Returns:

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

    raw messages as arrays



125
126
127
# File 'lib/cmdx/errors.rb', line 125

def to_h
  messages.transform_values(&:to_a)
end

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

Parameters:

Returns:

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


131
132
133
# File 'lib/cmdx/errors.rb', line 131

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)


148
149
150
# File 'lib/cmdx/errors.rb', line 148

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



154
155
156
# File 'lib/cmdx/errors.rb', line 154

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