Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 87 additions & 25 deletions spec/Section 6 -- Execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,21 @@ A GraphQL service generates a response from a request via execution.
being executed. Conceptually, an initial value represents the "universe" of
data available via a GraphQL Service. It is common for a GraphQL Service to
always use the same initial value for every request.
- {onError} (optional): The _error behavior_ to apply to the request; see
[Handling Execution Errors](#sec-Handling-Execution-Errors).
- {extensions} (optional): A map reserved for implementation-specific additional
information.

Given this information, the result of {ExecuteRequest(schema, document,
operationName, variableValues, initialValue)} produces the response, to be
formatted according to the Response section below.
operationName, variableValues, onError, initialValue)} produces the response, to
be formatted according to the Response section below.

Note: Previous versions of this specification did not define the {onError}
request attribute. In that case, clients should not include {onError} in the
request and assume the _error behavior_ is {"PROPAGATE"}.

Note: Detecting whether a service supports {onError} and what _default error
behavior_ it uses is outside the scope of this specification.

Implementations should not add additional properties to a _request_, which may
conflict with future editions of the GraphQL specification. Instead,
Expand All @@ -47,11 +56,14 @@ document is expected to only contain a single operation. The result of the
request is determined by the result of executing this operation according to the
"Executing Operations” section below.

ExecuteRequest(schema, document, operationName, variableValues, initialValue):
ExecuteRequest(schema, document, operationName, variableValues, onError,
initialValue):

- Let {operation} be the result of {GetOperation(document, operationName)}.
- Let {coercedVariableValues} be the result of {CoerceVariableValues(schema,
operation, variableValues)}.
- If {onError} is not one of {"NULL"}, {"PROPAGATE"}, or {"HALT"}, raise a
_request error_.
- If {operation} is a query operation:
- Return {ExecuteQuery(operation, schema, coercedVariableValues,
initialValue)}.
Expand Down Expand Up @@ -600,13 +612,26 @@ section.
</a>

If during {ExecuteCollectedFields()} a _response position_ with a non-null type
raises an _execution error_ then that error must propagate to the parent
response position (the entire selection set in the case of a field, or the
entire list in the case of a list position), either resolving to {null} if
allowed or being further propagated to a parent response position.

If this occurs, any sibling response positions which have not yet executed or
have not yet yielded a value may be cancelled to avoid unnecessary work.
raises an _execution error_, the error must be added to the {"errors"} list in
the _execution result_ and then handled according to the _error behavior_ of the
request:

- {"NULL"}: The _response position_ must be set to {null}, even if such position
is indicated by the schema to be non-nullable. (The client is responsible for
interpreting this {null} in conjunction with the {"errors"} list to
distinguish error results from intentional {null} values.)
- {"PROPAGATE"}: The _execution error_ must propagate to the parent _response
position_ (the entire selection set in the case of a field, or the entire list
in the case of a list position). The parent position resolves to {null} if
allowed, or else the error is further propagated to a parent response
position. Any sibling response positions that have not yet executed or have
not yet yielded a value may be cancelled to avoid unnecessary work.
- {"HALT"}: The current {ExecuteRootSelectionSet()} must be aborted immediately
and must yield an execution result with an {"errors"} list consisting of this
_execution error_ only and the {"data"} entry set to {null}. Any _response
position_ that has not yet executed or has not yet yielded a value may be
cancelled to avoid unnecessary work. (Note: For a subscription operation the
underlying stream is not terminated.)

Note: See [Handling Execution Errors](#sec-Handling-Execution-Errors) for more
about this behavior.
Expand Down Expand Up @@ -902,30 +927,57 @@ ResolveAbstractType(abstractType, objectValue):
</a>

An _execution error_ is an error raised during field execution, value resolution
or coercion, at a specific _response position_. While these errors must be
reported in the response, they are "handled" by producing partial {"data"} in
the _response_.
or coercion, at a specific _response position_. These errors must be added to
the {"errors"} list in the _response_, and are "handled" according to the _error
behavior_ of the request.

Note: An _execution error_ is distinct from a _request error_ which results in a
response with no {"data"}.

If a _response position_ resolves to {null} because of an execution error which
has already been added to the {"errors"} list in the _execution result_, the
{"errors"} list must not be further affected. That is, only one error should be
added to the errors list per _response position_.

:: The _error behavior_ of a request indicates how an _execution error_ is
handled. It may be specified using the optional {onError} attribute of the
_request_. If omitted, the _default error behavior_ of the service applies.
Valid values for _error behavior_ are {"NULL"}, {"PROPAGATE"} and {"HALT"}.

:: The _default error behavior_ of a service is implementation-defined.

Note: {"HALT"} is not recommended as the _default error behavior_ because it
prevents generating partial responses which may still contain useful data.

Regardless of error behavior, if a _response position_ with a non-null type
results in {null} due to the result of {ResolveFieldValue()} then an execution
error must be raised at that position as specified in {CompleteValue()}.

Note: This is distinct from a _request error_ which results in a _request error
result_ with no data.
The _error behavior_ of a request applies to every _execution error_ raised
during execution. The following sections describe the behavior of each valid
value:

If an execution error is raised while resolving a field (either directly or
nested inside any lists), it is handled as though the _response position_ at
which the error occurred resolved to {null}, and the error must be added to the
{"errors"} list in the _execution result_.
**{"NULL"}**

With {"NULL"}, a `Non-Null` _response position_ has the value {null} if and only
if an error occurred at that position.

Note: Clients must inspect the {"errors"} list and use the {"path"} of each
error result to distinguish between intentional {null} values and those
resulting from an _execution error_.

**{"PROPAGATE"}**

With {"PROPAGATE"}, a `Non-Null` _response position_ must not contain {null} in
the _response_.

If the result of resolving a _response position_ is {null} (either due to the
result of {ResolveFieldValue()} or because an execution error was raised), and
that position is of a `Non-Null` type, then an execution error is raised at that
position. The error must be added to the {"errors"} list in the _execution
result_.

If a _response position_ resolves to {null} because of an execution error which
has already been added to the {"errors"} list in the _execution result_, the
{"errors"} list must not be further affected. That is, only one error should be
added to the errors list per _response position_.

Since `Non-Null` response positions cannot be {null}, execution errors are
To avoid `Non-Null` response positions being {null}, execution errors are
propagated to be handled by the parent _response position_. If the parent
response position may be {null} then it resolves to {null}, otherwise if it is a
`Non-Null` type, the execution error is further propagated to its parent
Expand All @@ -939,3 +991,13 @@ position_ must resolve to {null}. If the `List` type is also wrapped in a
If every _response position_ from the root of the request to the source of the
execution error has a `Non-Null` type, then the {"data"} entry in the _execution
result_ should be {null}.

**{"HALT"}**

With {"HALT"}, {ExecuteRootSelectionSet()} must cease immediately that the first
_execution error_ is raised. That error must be added to the {"errors"} list,
and {"data"} must be {null}.

Note: For subscription operations, processing of the current event is ceased,
but the subscription still remains in place and future events will be processed
as normal.
Loading