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


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

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


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

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


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

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:



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

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
119
120
121
# File 'lib/cmdx/errors.rb', line 114

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)

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{Symbol => 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



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

def to_h
  messages.transform_values(&:to_a)
end

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

Parameters:

Returns:

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


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

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)


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

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



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

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