Exception: Ecoportal::API::Common::GraphQL::ResponseError
- Inherits:
-
StandardError
- Object
- StandardError
- Ecoportal::API::Common::GraphQL::ResponseError
- Defined in:
- lib/ecoportal/api/common/graphql/http_client.rb
Overview
Raised when a 200 response carries a top-level errors[] array.
★ Carries the RAW error entries, so extensions survives. Before this, the
class collapsed the response into the joined message text and threw the rest
away — which made it impossible for Ruby tooling to tell a permission problem
from a request problem, the exact diagnosis we tell customers to perform.
Tracked as Q-27 in docs/open-questions.md.
The backend's error contract (app/graphql/eco_portal_schema.rb, verified
2026-09-01) puts these keys under extensions:
| key | when | shape |
|---|---|---|
code |
always | string: unauthorized, document_not_found, unprocessable_entity, write_conflict, internal_server_error, … |
fullMessages |
unauthorized |
array of human strings (exp.result.reasons.full_messages) |
details |
unauthorized |
ActionPolicy reasons.details — usually a Hash whose key names the failing policy and whose value lists the rules |
problems |
validation, and only when the server runs with SHOW_GRAPHQL_EXCEPTION |
record errors |
⚠ details is NOT reliably a Hash. Two call sites emit an Array instead
(mutations/pages/send_as_email.rb sends inaccessible ids;
queries/pages/templates/fetcher.rb sends [msg]). Accessors here therefore
return whatever the server sent, unwrapped but uncoerced — callers must not
assume a shape.
Instance Attribute Summary collapse
-
#errors ⇒ Array<Hash>
readonly
The raw
errors[]entries, exactly as received.
Instance Method Summary collapse
-
#codes ⇒ Array<String>
Every
extensions.codepresent, in order. -
#details ⇒ Array
★ The fastest way to tell a permission problem from a request problem.
-
#extensions ⇒ Array<Hash>
The
extensionsobject of each error that carried one. -
#full_messages ⇒ Array<String>
Flattened
extensions.fullMessages. -
#initialize(msg = nil, errors: []) ⇒ ResponseError
constructor
A new instance of ResponseError.
-
#unauthorized? ⇒ Boolean
Whether ANY error was an authorization refusal.
Constructor Details
#initialize(msg = nil, errors: []) ⇒ ResponseError
Returns a new instance of ResponseError.
34 35 36 37 |
# File 'lib/ecoportal/api/common/graphql/http_client.rb', line 34 def initialize(msg = nil, errors: []) @errors = Array(errors) super(msg || ) end |
Instance Attribute Details
#errors ⇒ Array<Hash> (readonly)
Returns the raw errors[] entries, exactly as received.
30 31 32 |
# File 'lib/ecoportal/api/common/graphql/http_client.rb', line 30 def errors @errors end |
Instance Method Details
#codes ⇒ Array<String>
Returns every extensions.code present, in order.
45 46 47 |
# File 'lib/ecoportal/api/common/graphql/http_client.rb', line 45 def codes extensions.filter_map { |ext| ext['code'] } end |
#details ⇒ Array
★ The fastest way to tell a permission problem from a request problem.
52 53 54 |
# File 'lib/ecoportal/api/common/graphql/http_client.rb', line 52 def details extensions.filter_map { |ext| ext['details'] } end |
#extensions ⇒ Array<Hash>
Returns the extensions object of each error that carried one.
40 41 42 |
# File 'lib/ecoportal/api/common/graphql/http_client.rb', line 40 def extensions errors.filter_map { |err| err['extensions'] } end |
#full_messages ⇒ Array<String>
Returns flattened extensions.fullMessages.
57 58 59 |
# File 'lib/ecoportal/api/common/graphql/http_client.rb', line 57 def extensions.flat_map { |ext| Array(ext['fullMessages']) } end |
#unauthorized? ⇒ Boolean
Returns whether ANY error was an authorization refusal. Use this to branch on "you cannot" vs "that request was wrong" — do not pattern-match the message text, which is prose and drifts.
64 65 66 |
# File 'lib/ecoportal/api/common/graphql/http_client.rb', line 64 def codes.include?('unauthorized') end |