class GraphQL::Client::Errors

Inspired by ActiveModel::Errors.
Public: Collection of errors associated with GraphQL object type.

def self.normalize_error_paths(data = nil, errors = [])

Returns nothing.

errors - Array of error Hashes
data - Hash of response data

Records "normalizedPath" value to error object.

Internal: Normalize GraphQL Error "path" ensuring the path exists.
def self.normalize_error_paths(data = nil, errors = [])
  errors.each do |error|
    path = ["data"]
    current = data
    error["path"].to_a.each do |key|
      break unless current
      path << key
      current = current[key]
    end
    error["normalizedPath"] = path
  end
  errors
end

def [](key)

Returns Array of errors.

data.errors['node'] # => ["couldn't find node by id"]
data.errors[:node] # => ["couldn't find node by id"]

errors for the method.
Public: When passed a symbol or a name of a field, returns an array of
def [](key)
  messages.fetch(key, [])
end

def all

Returns Errors collection.

data.errors.all[:node]
data.errors[:node]

Public: Return collection of all nested errors.
def all
  if @all
    self
  else
    self.class.new(@raw_errors, @ast_path, true)
  end
end

def details

Returns HashWithIndifferentAccess.

data.errors.details[:node]
data.errors.details["node"]

Public: Access Hash of error objects.
def details
  return @details if defined? @details
  details = {}
  @raw_errors.each do |error|
    path = error.fetch("normalizedPath", [])
    matched_path = @all ? path[0, @ast_path.length] : path[0...-1]
    next unless @ast_path == matched_path
    field = path[@ast_path.length]
    next unless field
    details[field] ||= []
    details[field] << error
  end
  @details = HashWithIndifferentAccess.new(details)
end

def each

message.
field has more than one error message, yields once for each error
messages hash. Yields the field and the error for that attribute. If the
Public: Iterates through each error key, value pair in the error
def each
  return enum_for(:each) unless block_given?
  messages.each_key do |field|
    messages[field].each { |error| yield field, error }
  end
end

def empty?

Returns true if no errors are found, otherwise false.

data.errors.empty? # => false
data.errors.messages # => {"node"=>["couldn't find node by id"]}

Public: Check if there are no errors on object.
def empty?
  size.zero?
end

def filter_by_path(field)

Returns Errors collection.

data.errors.filter_by_path("node")

Internal: Return collection of errors for a given subfield.
def filter_by_path(field)
  self.class.new(@raw_errors, @ast_path + [field], @all)
end

def include?(field)

otherwise false.
Returns true if the error messages include an error for the given field,

data.errors.include?("version") # => false
data.errors.include?("node") # => true
data.errors.messages # => {"node"=>["couldn't find node by id", "unauthorized"]}

Public: Check if there are any errors on a given field.
def include?(field)
  self[field].any?
end

def initialize(errors = [], path = [], all = false)

all - Boolean flag if all nested errors should be available
path - Array of String|Integer fields to data
errors - Array of GraphQL Hash error objects

Internal: Initialize from collection of errors.
def initialize(errors = [], path = [], all = false)
  @ast_path = path
  @all = all
  @raw_errors = errors
end

def inspect

Returns String.

Public: Display console friendly representation of errors collection.
def inspect
  "#<#{self.class} @messages=#{messages.inspect} @details=#{details.inspect}>"
end

def keys

Returns Array of String field names.

data.errors.values # => ["node"]
data.errors.messages # => {"node"=>["couldn't find node by id"]}

Public: Returns all message keys.
def keys
  messages.keys
end

def messages

Returns HashWithIndifferentAccess.

data.errors.messages[:node]
data.errors.messages["node"]

Public: Access Hash of error messages.
def messages
  return @messages if defined? @messages
  messages = {}
  details.each do |field, errors|
    messages[field] ||= []
    errors.each do |error|
      messages[field] << error.fetch("message")
    end
  end
  @messages = HashWithIndifferentAccess.new(messages)
end

def size

Returns the number of error messages.

data.errors.size # => 2
data.errors.messages # => {"node"=>["couldn't find node by id", "unauthorized"]}

Public: Count the number of errors on object.
def size
  values.flatten.size
end

def values

Returns Array of Array String messages.

data.errors.values # => [["couldn't find node by id"]]
data.errors.messages # => {"node"=>["couldn't find node by id"]}

Public: Returns all message values.
def values
  messages.values
end