Module: GraphWeaver::Testing::Failure
- Includes:
- Kernel
- Defined in:
- lib/graph_weaver/testing/failure.rb
Overview
Canned failure clients — each produces exactly what the real transports produce, so error-handling paths are testable without a server that misbehaves on cue:
PersonQuery.execute(id: "1", Failure.transport) # TransportError
PersonQuery.execute(id: "1", Failure.server(status: 502))
PersonQuery.execute(id: "1", Failure.throttled) # QueryError, code THROTTLED
PersonQuery.execute(id: "1", Failure.stale_schema) # schema_stale? => true
For type mismatches, corrupt the wire with a FakeClient override: FakeClient.new(schema:, overrides: { "Person.birthday" => 123 }) casting then raises GraphWeaver::TypeError, exactly as a bad server payload would. For partial failures, see FakeClient's fail_at:.
Class Method Summary collapse
-
.graphql(*errors, data: nil, extensions: {}) ⇒ Object
top-level GraphQL errors: strings, or hashes with message/path/ extensions; data: rides along for partial-failure envelopes.
-
.server(status: 500, body: "simulated server error") ⇒ Object
the server answered non-2xx.
-
.stale_schema(field: nil, type: nil, schema: nil, seed: nil) ⇒ Object
A validation-shaped rejection — trips schema_stale? and its regenerate hint, as if the schema changed under the module.
- .throttled ⇒ Object
-
.transport(message = "simulated network failure", cause: SocketError) ⇒ Object
the request never reaches the server — cause preserved, like the bundled transports do.
Class Method Details
.graphql(*errors, data: nil, extensions: {}) ⇒ Object
top-level GraphQL errors: strings, or hashes with message/path/ extensions; data: rides along for partial-failure envelopes
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/graph_weaver/testing/failure.rb', line 42 def graphql(*errors, data: nil, extensions: {}) normalized = errors.flatten.map do |error| error.is_a?(String) ? { "message" => error } : JSON.parse(JSON.generate(error)) end response = { "errors" => normalized } response["data"] = data if data response["extensions"] = JSON.parse(JSON.generate(extensions)) unless extensions.empty? FailureClient.new { response } end |
.server(status: 500, body: "simulated server error") ⇒ Object
the server answered non-2xx
36 37 38 |
# File 'lib/graph_weaver/testing/failure.rb', line 36 def server(status: 500, body: "simulated server error") FailureClient.new { raise GraphWeaver::ServerError.new(status:, body:) } end |
.stale_schema(field: nil, type: nil, schema: nil, seed: nil) ⇒ Object
A validation-shaped rejection — trips schema_stale? and its regenerate hint, as if the schema changed under the module. Name the casualty explicitly, or pass schema: to sample a real type/field (as if the server just dropped it):
Failure.stale_schema(type: "Person", field: "name")
Failure.stale_schema(schema: MySchema) # random real field
Failure.stale_schema(schema: MySchema, seed: 42) # reproducibly random
66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/graph_weaver/testing/failure.rb', line 66 def stale_schema(field: nil, type: nil, schema: nil, seed: nil) if schema && (field.nil? || type.nil?) rng = Random.new(seed || GraphWeaver::Testing.config.seed || Random.new_seed) candidates = schema.types.values.select do |candidate| candidate.kind.name == "OBJECT" && !candidate.graphql_name.start_with?("__") end chosen = candidates.sort_by(&:graphql_name).sample(random: rng) type ||= chosen.graphql_name field ||= chosen.fields.keys.sort.sample(random: rng) end graphql("Field '#{field || "someField"}' doesn't exist on type '#{type || "SomeType"}'") end |
.throttled ⇒ Object
53 54 55 56 |
# File 'lib/graph_weaver/testing/failure.rb', line 53 def throttled # array-wrapped so the hash can't parse as kwargs graphql([{ message: "rate limited", extensions: { code: "THROTTLED" } }]) end |
.transport(message = "simulated network failure", cause: SocketError) ⇒ Object
the request never reaches the server — cause preserved, like the bundled transports do
27 28 29 30 31 32 33 |
# File 'lib/graph_weaver/testing/failure.rb', line 27 def transport( = "simulated network failure", cause: SocketError) FailureClient.new do raise cause, rescue cause => e raise GraphWeaver::TransportError, e. end end |