Module: GraphWeaver::ErrorFiltering

Extended by:
T::Sig
Includes:
Kernel
Included in:
QueryError, Response
Defined in:
lib/graph_weaver/errors.rb

Overview

Shared filtering over a collection of GraphQLErrors, for surfacing field-level failures programmatically. Host must define #errors / #data.

Instance Method Summary collapse

Instance Method Details

#dataObject

Raises:

  • (NotImplementedError)


227
228
229
# File 'lib/graph_weaver/errors.rb', line 227

def data
  raise NotImplementedError, "#{self.class} must define #data"
end

#each_error(&block) ⇒ Object



266
267
268
# File 'lib/graph_weaver/errors.rb', line 266

def each_error(&block)
  errors_by_field.each { |field, errs| block.call(field, errs) }
end

#entity_id(error) ⇒ Object



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/graph_weaver/errors.rb', line 275

def entity_id(error)
  # untyped by nature: the walk traverses whatever structs this query
  # generated, reassigning across types at each step
  node = T.let(data, T.untyped)
  path = error.path
  return unless node && path

  (path[0..-2] || []).each do |segment|
    node = if segment.is_a?(Integer) || segment.to_s.match?(/\A\d+\z/)
      node.is_a?(Array) ? node[segment.to_i] : nil
    else
      prop = GraphWeaver::Inflect.underscore(segment.to_s).to_sym
      node.respond_to?(prop) ? node.public_send(prop) : nil
    end
    return if node.nil?
  end

  node.respond_to?(:id) ? node.id : nil
end

#errorsObject

Raises:

  • (NotImplementedError)


222
223
224
# File 'lib/graph_weaver/errors.rb', line 222

def errors
  raise NotImplementedError, "#{self.class} must define #errors"
end

#errors_at(path) ⇒ Object



235
236
237
238
239
240
241
# File 'lib/graph_weaver/errors.rb', line 235

def errors_at(path)
  want = (path.is_a?(String) ? path.split(".") : path).map(&:to_s)
  errors.select do |error|
    p = error.path
    p && p.map(&:to_s).first(want.size) == want
  end
end

#errors_by_fieldObject



259
260
261
# File 'lib/graph_weaver/errors.rb', line 259

def errors_by_field
  errors.group_by(&:field)
end

#reportObject



302
303
304
305
306
307
308
309
310
311
# File 'lib/graph_weaver/errors.rb', line 302

def report
  errors_by_field.to_h do |field, field_errors|
    [field, {
      "messages" => field_errors.map(&:message),
      "codes" => field_errors.filter_map(&:code).uniq,
      "entity_ids" => field_errors.filter_map { |e| entity_id(e) }.uniq,
      "errors" => field_errors.map(&:to_h),
    }]
  end
end

#schema_stale?Boolean

Returns:

  • (Boolean)


248
249
250
# File 'lib/graph_weaver/errors.rb', line 248

def schema_stale?
  errors.any?(&:validation?)
end