From 920283ac96be6caf72cb29d7b0480561d57fdeab Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 27 Mar 2025 10:16:51 +0000 Subject: [PATCH 1/9] Rename 'field error' to 'runtime error' and define 'error position' --- spec/Section 3 -- Type System.md | 63 +++++++++++----------- spec/Section 5 -- Validation.md | 2 +- spec/Section 6 -- Execution.md | 92 ++++++++++++++++++-------------- spec/Section 7 -- Response.md | 42 ++++++++++----- 4 files changed, 113 insertions(+), 86 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 945c916f6..7a5187a3b 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -329,8 +329,8 @@ A GraphQL schema may describe that a field represents a list of another type; the `List` type is provided for this reason, and wraps another type. Similarly, the `Non-Null` type wraps another type, and denotes that the -resulting value will never be {null} (and that a _field error_ cannot result in -a {null} value). +resulting value will never be {null} (and that a _runtime error_ cannot result +in a {null} value). These two types are referred to as "wrapping types"; non-wrapping types are referred to as "named types". A wrapping type has an underlying named type, @@ -461,14 +461,14 @@ more guidance. A GraphQL service, when preparing a field of a given scalar type, must uphold the contract the scalar type describes, either by coercing the value or -producing a _field error_ if a value cannot be coerced or if coercion may result -in data loss. +producing a _runtime error_ if a value cannot be coerced or if coercion may +result in data loss. A GraphQL service may decide to allow coercing different internal types to the expected return type. For example when coercing a field of type {Int} a boolean {true} value may produce {1} or a string value {"123"} may be parsed as base-10 {123}. However if internal type coercion cannot be reasonably performed without -losing information, then it must raise a _field error_. +losing information, then it must raise a _runtime error_. Since this coercion behavior is not observable to clients of the GraphQL service, the precise rules of coercion are left to the implementation. The only @@ -513,15 +513,15 @@ Fields returning the type {Int} expect to encounter 32-bit integer internal values. GraphQL services may coerce non-integer internal values to integers when -reasonable without losing information, otherwise they must raise a _field +reasonable without losing information, otherwise they must raise a _runtime error_. Examples of this may include returning `1` for the floating-point number `1.0`, or returning `123` for the string `"123"`. In scenarios where coercion -may lose data, raising a field error is more appropriate. For example, a -floating-point number `1.2` should raise a field error instead of being +may lose data, raising a runtime error is more appropriate. For example, a +floating-point number `1.2` should raise a runtime error instead of being truncated to `1`. If the integer internal value represents a value less than -231 or -greater than or equal to 231, a _field error_ should be raised. +greater than or equal to 231, a _runtime error_ should be raised. **Input Coercion** @@ -548,12 +548,12 @@ Fields returning the type {Float} expect to encounter double-precision floating-point internal values. GraphQL services may coerce non-floating-point internal values to {Float} when -reasonable without losing information, otherwise they must raise a _field +reasonable without losing information, otherwise they must raise a _runtime error_. Examples of this may include returning `1.0` for the integer number `1`, or `123.0` for the string `"123"`. Non-finite floating-point internal values ({NaN} and {Infinity}) cannot be -coerced to {Float} and must raise a _field error_. +coerced to {Float} and must raise a _runtime error_. **Input Coercion** @@ -579,9 +579,9 @@ that representation must be used to serialize this type. Fields returning the type {String} expect to encounter Unicode string values. GraphQL services may coerce non-string raw values to {String} when reasonable -without losing information, otherwise they must raise a _field error_. Examples -of this may include returning the string `"true"` for a boolean true value, or -the string `"1"` for the integer `1`. +without losing information, otherwise they must raise a _runtime error_. +Examples of this may include returning the string `"true"` for a boolean true +value, or the string `"1"` for the integer `1`. **Input Coercion** @@ -600,8 +600,8 @@ representation of the integers `1` and `0`. Fields returning the type {Boolean} expect to encounter boolean internal values. GraphQL services may coerce non-boolean raw values to {Boolean} when reasonable -without losing information, otherwise they must raise a _field error_. Examples -of this may include returning `true` for non-zero numbers. +without losing information, otherwise they must raise a _runtime error_. +Examples of this may include returning `true` for non-zero numbers. **Input Coercion** @@ -623,7 +623,7 @@ large 128-bit random numbers, to base64 encoded values, or string values of a format like [GUID](https://en.wikipedia.org/wiki/Globally_unique_identifier). GraphQL services should coerce as appropriate given the ID formats they expect. -When coercion is not possible they must raise a _field error_. +When coercion is not possible they must raise a _runtime error_. **Input Coercion** @@ -1492,7 +1492,7 @@ enum Direction { **Result Coercion** GraphQL services must return one of the defined set of possible values. If a -reasonable coercion is not possible they must raise a _field error_. +reasonable coercion is not possible they must raise a _runtime error_. **Input Coercion** @@ -1654,10 +1654,10 @@ is constructed with the following rules: - If a variable is provided for an input object field, the runtime value of that variable must be used. If the runtime value is {null} and the field type is - non-null, a _field error_ must be raised. If no runtime value is provided, the - variable definition's default value should be used. If the variable definition - does not provide a default value, the input object field definition's default - value should be used. + non-null, a _runtime error_ must be raised. If no runtime value is provided, + the variable definition's default value should be used. If the variable + definition does not provide a default value, the input object field + definition's default value should be used. Following are examples of input coercion for an input object type with a `String` field `a` and a required (non-null) `Int!` field `b`: @@ -1742,18 +1742,18 @@ brackets like this: `pets: [Pet]`. Nesting lists is allowed: `matrix: [[Int]]`. GraphQL services must return an ordered list as the result of a list type. Each item in the list must be the result of a result coercion of the item type. If a -reasonable coercion is not possible it must raise a _field error_. In +reasonable coercion is not possible it must raise a _runtime error_. In particular, if a non-list is returned, the coercion should fail, as this indicates a mismatch in expectations between the type system and the implementation. If a list's item type is nullable, then errors occurring during preparation or coercion of an individual item in the list must result in a the value {null} at -that position in the list along with a _field error_ added to the response. If a -list's item type is non-null, a field error occurring at an individual item in -the list must result in a field error for the entire list. +that position in the list along with a _runtime error_ added to the response. If +a list's item type is non-null, a runtime error occurring at an individual item +in the list must result in a runtime error for the entire list. -Note: See [Handling Field Errors](#sec-Handling-Field-Errors) for more about +Note: See [Handling Runtime Errors](#sec-Handling-Runtime-Errors) for more about this behavior. **Input Coercion** @@ -1812,12 +1812,13 @@ always optional and non-null types are always required. In all of the above result coercions, {null} was considered a valid value. To coerce the result of a Non-Null type, the coercion of the wrapped type should be performed. If that result was not {null}, then the result of coercing the -Non-Null type is that result. If that result was {null}, then a _field error_ +Non-Null type is that result. If that result was {null}, then a _runtime error_ must be raised. -Note: When a _field error_ is raised on a non-null value, the error propagates -to the parent field. For more information on this process, see -[Errors and Non-Null Fields](#sec-Executing-Selection-Sets.Errors-and-Non-Null-Fields) +Note: When a _runtime error_ is raised on a non-null _response position_, the +error propagates to the parent _response position_. For more information on this +process, see +[Errors and Non-Null Types](#sec-Executing-Selection-Sets.Errors-and-Non-Null-Types) within the Execution section. **Input Coercion** diff --git a/spec/Section 5 -- Validation.md b/spec/Section 5 -- Validation.md index 44bc9dbba..3ad186d1a 100644 --- a/spec/Section 5 -- Validation.md +++ b/spec/Section 5 -- Validation.md @@ -2010,4 +2010,4 @@ query booleanArgQueryWithDefault($booleanArg: Boolean = true) { ``` Note: The value {null} could still be provided to such a variable at runtime. A -non-null argument must raise a _field error_ if provided a {null} value. +non-null argument must raise a _runtime error_ if provided a {null} value. diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index d88c685f9..be68b306b 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -137,7 +137,7 @@ ExecuteQuery(query, schema, variableValues, initialValue): - Let {data} be the result of running {ExecuteSelectionSet(selectionSet, queryType, initialValue, variableValues)} _normally_ (allowing parallelization). -- Let {errors} be the list of all _field error_ raised while executing the +- Let {errors} be the list of all _runtime error_ raised while executing the selection set. - Return an unordered map containing {data} and {errors}. @@ -158,7 +158,7 @@ ExecuteMutation(mutation, schema, variableValues, initialValue): - Let {selectionSet} be the top level selection set in {mutation}. - Let {data} be the result of running {ExecuteSelectionSet(selectionSet, mutationType, initialValue, variableValues)} _serially_. -- Let {errors} be the list of all _field error_ raised while executing the +- Let {errors} be the list of all _runtime error_ raised while executing the selection set. - Return an unordered map containing {data} and {errors}. @@ -317,10 +317,10 @@ MapSourceToResponseEvent(sourceStream, subscription, schema, variableValues): - Complete {responseStream} normally. - Return {responseStream}. -Note: Since {ExecuteSubscriptionEvent()} handles all _field error_, and _request -error_ only occur during {CreateSourceEventStream()}, the only remaining error -condition handled from {ExecuteSubscriptionEvent()} are internal exceptional -errors not described by this specification. +Note: Since {ExecuteSubscriptionEvent()} handles all _runtime error_, and +_request error_ only occur during {CreateSourceEventStream()}, the only +remaining error condition handled from {ExecuteSubscriptionEvent()} are internal +exceptional errors not described by this specification. ExecuteSubscriptionEvent(subscription, schema, variableValues, initialValue): @@ -330,7 +330,7 @@ ExecuteSubscriptionEvent(subscription, schema, variableValues, initialValue): - Let {data} be the result of running {ExecuteSelectionSet(selectionSet, subscriptionType, initialValue, variableValues)} _normally_ (allowing parallelization). -- Let {errors} be the list of all _field error_ raised while executing the +- Let {errors} be the list of all _runtime error_ raised while executing the selection set. - Return an unordered map containing {data} and {errors}. @@ -377,16 +377,22 @@ ExecuteSelectionSet(selectionSet, objectType, objectValue, variableValues): Note: {resultMap} is ordered by which fields appear first in the operation. This is explained in greater detail in the Field Collection section below. -**Errors and Non-Null Fields** + + + -If during {ExecuteSelectionSet()} a field with a non-null {fieldType} raises a -_field error_ then that error must propagate to this entire selection set, -either resolving to {null} if allowed or further propagated to a parent field. +**Errors and Non-Null Types** -If this occurs, any sibling fields which have not yet executed or have not yet -yielded a value may be cancelled to avoid unnecessary work. +If during {ExecuteSelectionSet()} a _response position_ with a non-null type +raises a _runtime 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_. -Note: See [Handling Field Errors](#sec-Handling-Field-Errors) for more about +If this occurs, any sibling response position which have not yet executed or +have not yet yielded a value may be cancelled to avoid unnecessary work. + +Note: See [Handling Runtime Errors](#sec-Handling-Runtime-Errors) for more about this behavior. ### Normal and Serial Execution @@ -647,7 +653,7 @@ CoerceArgumentValues(objectType, field, variableValues): - Add an entry to {coercedValues} named {argumentName} with the value {defaultValue}. - Otherwise if {argumentType} is a Non-Nullable type, and either {hasValue} is - not {true} or {value} is {null}, raise a _field error_. + not {true} or {value} is {null}, raise a _runtime error_. - Otherwise if {hasValue} is {true}: - If {value} is {null}: - Add an entry to {coercedValues} named {argumentName} with the value @@ -657,7 +663,7 @@ CoerceArgumentValues(objectType, field, variableValues): {value}. - Otherwise: - If {value} cannot be coerced according to the input coercion rules of - {argumentType}, raise a _field error_. + {argumentType}, raise a _runtime error_. - Let {coercedValue} be the result of coercing {value} according to the input coercion rules of {argumentType}. - Add an entry to {coercedValues} named {argumentName} with the value @@ -704,12 +710,12 @@ CompleteValue(fieldType, fields, result, variableValues): - Let {innerType} be the inner type of {fieldType}. - Let {completedResult} be the result of calling {CompleteValue(innerType, fields, result, variableValues)}. - - If {completedResult} is {null}, raise a _field error_. + - If {completedResult} is {null}, raise a _runtime error_. - Return {completedResult}. - If {result} is {null} (or another internal value similar to {null} such as {undefined}), return {null}. - If {fieldType} is a List type: - - If {result} is not a collection of values, raise a _field error_. + - If {result} is not a collection of values, raise a _runtime error_. - Let {innerType} be the inner type of {fieldType}. - Return a list where each list item is the result of calling {CompleteValue(innerType, fields, resultItem, variableValues)}, where @@ -744,7 +750,7 @@ CoerceResult(leafType, value): - Return the result of calling the internal method provided by the type system for determining the "result coercion" of {leafType} given the value {value}. This internal method must return a valid value for the type and not {null}. - Otherwise raise a _field error_. + Otherwise raise a _runtime error_. Note: If a field resolver returns {null} then it is handled within {CompleteValue()} before {CoerceResult()} is called. Therefore both the input @@ -799,39 +805,45 @@ MergeSelectionSets(fields): - Append all selections in {fieldSelectionSet} to {selectionSet}. - Return {selectionSet}. -### Handling Field Errors + + + + +### Handling Runtime Errors -A _field error_ is an error raised from a particular field during value +A _runtime error_ is an error raised from a particular field during value resolution or coercion. While these errors should be reported in the response, they are "handled" by producing a partial response. Note: This is distinct from a _request error_ which results in a response with no data. -If a field error is raised while resolving a field, it is handled as though the -field returned {null}, and the error must be added to the {"errors"} list in the -response. +If a runtime error is raised while resolving a field (either directly or nested +inside any lists), it is handled as though the position at which the error +occurred resulted in {null}, and the error must be added to the {"errors"} list +in the response. -If the result of resolving a field is {null} (either because the function to -resolve the field returned {null} or because a field error was raised), and that -field is of a `Non-Null` type, then a field error is raised. The error must be -added to the {"errors"} list in the response. +If the result of resolving a _response position_ is {null} (either due to the +result of {ResolveFieldValue()} or because a runtime error was raised), and that +position is of a `Non-Null` type, then a runtime error is raised at that +position. The error must be added to the {"errors"} list in the response. -If the field returns {null} because of a field error which has already been -added to the {"errors"} list in the response, the {"errors"} list must not be -further affected. That is, only one error should be added to the errors list per -field. +If a _response position_ returns {null} because of a runtime error which has +already been added to the {"errors"} list in the response, 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` type fields cannot be {null}, field errors are propagated to be -handled by the parent field. If the parent field may be {null} then it resolves -to {null}, otherwise if it is a `Non-Null` type, the field error is further -propagated to its parent field. +Since `Non-Null` response positions cannot be {null}, runtime 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 runtime error is further propagated to its parent _response +position_. If a `List` type wraps a `Non-Null` type, and one of the elements of that list resolves to {null}, then the entire list must resolve to {null}. If the `List` -type is also wrapped in a `Non-Null`, the field error continues to propagate +type is also wrapped in a `Non-Null`, the runtime error continues to propagate upwards. -If all fields from the root of the request to the source of the field error -return `Non-Null` types, then the {"data"} entry in the response should be -{null}. +If all response positions from the root of the request to the source of the +runtime error return `Non-Null` types, then the {"data"} entry in the response +should be {null}. diff --git a/spec/Section 7 -- Response.md b/spec/Section 7 -- Response.md index daca5bb1f..fbac9646d 100644 --- a/spec/Section 7 -- Response.md +++ b/spec/Section 7 -- Response.md @@ -5,8 +5,7 @@ response. The service's response describes the result of executing the requested operation if successful, and describes any errors raised during the request. A response may contain both a partial response as well as a list of errors in -the case that any _field error_ was raised on a field and was replaced with -{null}. +the case that any _runtime error_ was raised and replaced with {null}. ## Response Format @@ -73,7 +72,7 @@ present. It must contain at least one _request error_ indicating why no data was able to be returned. If the `data` entry in the response is present (including if it is the value -{null}), the `errors` entry must be present if and only if one or more _field +{null}), the `errors` entry must be present if and only if one or more _runtime error_ was raised during execution. **Request Errors** @@ -89,18 +88,33 @@ If a request error is raised, the `data` entry in the response must not be present, the `errors` entry must include the error, and request execution should be halted. -**Field Errors** + + + -:: A _field error_ is an error raised during the execution of a particular field -which results in partial response data. This may occur due to an internal error -during value resolution or failure to coerce the resulting value. +**Runtime Errors** -A field error is typically the fault of a GraphQL service. +:: A _runtime error_ is an error raised during the execution of a particular +field which results in partial response data. This may occur due to failure to +coerce the arguments for the field, an internal error during value resolution, +or failure to coerce the resulting value. A _runtime error_ may occur in any +_response position_. -If a field error is raised, execution attempts to continue and a partial result -is produced (see [Handling Field Errors](#sec-Handling-Field-Errors)). The -`data` entry in the response must be present. The `errors` entry should include -this error. +Note: In previous versions of this specification _runtime error_ was called +_field error_. + +:: A _response position_ is an identifiable position in the response: either a +_field_, or a (potentially nested) list position within a field if the field has +a `List` type. A _runtime error_ may only occur within a _response position_. +The _response position_ is indicated in the _response_ via the error's _path +entry_. + +A runtime error is typically the fault of a GraphQL service. + +If a runtime error is raised, execution attempts to continue and a partial +result is produced (see +[Handling Runtime Errors](#sec-Handling-Runtime-Errors)). The `data` entry in +the response must be present. The `errors` entry must include this error. **Error Result Format** @@ -250,8 +264,8 @@ discouraged. ### Path -:: A _path entry_ is an entry within an _error result_ that allows for -association with a particular field reached during GraphQL execution. +:: A _path entry_ is an entry within an _error result_ that indicates the +_response position_ at which the error occurred. The value for a _path entry_ must be a list of path segments starting at the root of the response and ending with the field to be associated with. Path From 03460ff86d3049a555bd3ea9040b64f27782a3b7 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 27 Mar 2025 10:58:04 +0000 Subject: [PATCH 2/9] Request errors should not be raised during CoerceArgumentValues --- spec/Section 6 -- Execution.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index be68b306b..946ab4614 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -627,6 +627,9 @@ the type system to have a specific input type. At each argument position in an operation may be a literal {Value}, or a {Variable} to be provided at runtime. +Any _request error_ raised during {CoerceArgumentValues()} should be treated +instead as a _runtime error_. + CoerceArgumentValues(objectType, field, variableValues): - Let {coercedValues} be an empty unordered Map. From c5eed341b4a5468eff74b8e7292311115a5cb9c5 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 27 Mar 2025 11:15:58 +0000 Subject: [PATCH 3/9] Typo --- spec/Section 6 -- Execution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 946ab4614..21b897a50 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -387,9 +387,9 @@ If during {ExecuteSelectionSet()} a _response position_ with a non-null type raises a _runtime 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_. +further propagated to a parent response position. -If this occurs, any sibling response position which have not yet executed or +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. Note: See [Handling Runtime Errors](#sec-Handling-Runtime-Errors) for more about From fdc2b81474dea3dfde173b1af4f5d10925f73dd6 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 27 Mar 2025 11:34:31 +0000 Subject: [PATCH 4/9] Rename 'runtime error' to 'execution error' --- spec/Section 3 -- Type System.md | 48 ++++++++++++++-------------- spec/Section 5 -- Validation.md | 2 +- spec/Section 6 -- Execution.md | 54 ++++++++++++++++---------------- spec/Section 7 -- Response.md | 24 +++++++------- 4 files changed, 64 insertions(+), 64 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 7a5187a3b..0a865d08c 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -329,8 +329,8 @@ A GraphQL schema may describe that a field represents a list of another type; the `List` type is provided for this reason, and wraps another type. Similarly, the `Non-Null` type wraps another type, and denotes that the -resulting value will never be {null} (and that a _runtime error_ cannot result -in a {null} value). +resulting value will never be {null} (and that an _execution error_ cannot +result in a {null} value). These two types are referred to as "wrapping types"; non-wrapping types are referred to as "named types". A wrapping type has an underlying named type, @@ -461,14 +461,14 @@ more guidance. A GraphQL service, when preparing a field of a given scalar type, must uphold the contract the scalar type describes, either by coercing the value or -producing a _runtime error_ if a value cannot be coerced or if coercion may +producing an _execution error_ if a value cannot be coerced or if coercion may result in data loss. A GraphQL service may decide to allow coercing different internal types to the expected return type. For example when coercing a field of type {Int} a boolean {true} value may produce {1} or a string value {"123"} may be parsed as base-10 {123}. However if internal type coercion cannot be reasonably performed without -losing information, then it must raise a _runtime error_. +losing information, then it must raise an _execution error_. Since this coercion behavior is not observable to clients of the GraphQL service, the precise rules of coercion are left to the implementation. The only @@ -513,15 +513,15 @@ Fields returning the type {Int} expect to encounter 32-bit integer internal values. GraphQL services may coerce non-integer internal values to integers when -reasonable without losing information, otherwise they must raise a _runtime +reasonable without losing information, otherwise they must raise an _execution error_. Examples of this may include returning `1` for the floating-point number `1.0`, or returning `123` for the string `"123"`. In scenarios where coercion -may lose data, raising a runtime error is more appropriate. For example, a -floating-point number `1.2` should raise a runtime error instead of being +may lose data, raising an execution error is more appropriate. For example, a +floating-point number `1.2` should raise an execution error instead of being truncated to `1`. If the integer internal value represents a value less than -231 or -greater than or equal to 231, a _runtime error_ should be raised. +greater than or equal to 231, an _execution error_ should be raised. **Input Coercion** @@ -548,12 +548,12 @@ Fields returning the type {Float} expect to encounter double-precision floating-point internal values. GraphQL services may coerce non-floating-point internal values to {Float} when -reasonable without losing information, otherwise they must raise a _runtime +reasonable without losing information, otherwise they must raise an _execution error_. Examples of this may include returning `1.0` for the integer number `1`, or `123.0` for the string `"123"`. Non-finite floating-point internal values ({NaN} and {Infinity}) cannot be -coerced to {Float} and must raise a _runtime error_. +coerced to {Float} and must raise an _execution error_. **Input Coercion** @@ -579,7 +579,7 @@ that representation must be used to serialize this type. Fields returning the type {String} expect to encounter Unicode string values. GraphQL services may coerce non-string raw values to {String} when reasonable -without losing information, otherwise they must raise a _runtime error_. +without losing information, otherwise they must raise an _execution error_. Examples of this may include returning the string `"true"` for a boolean true value, or the string `"1"` for the integer `1`. @@ -600,7 +600,7 @@ representation of the integers `1` and `0`. Fields returning the type {Boolean} expect to encounter boolean internal values. GraphQL services may coerce non-boolean raw values to {Boolean} when reasonable -without losing information, otherwise they must raise a _runtime error_. +without losing information, otherwise they must raise an _execution error_. Examples of this may include returning `true` for non-zero numbers. **Input Coercion** @@ -623,7 +623,7 @@ large 128-bit random numbers, to base64 encoded values, or string values of a format like [GUID](https://en.wikipedia.org/wiki/Globally_unique_identifier). GraphQL services should coerce as appropriate given the ID formats they expect. -When coercion is not possible they must raise a _runtime error_. +When coercion is not possible they must raise an _execution error_. **Input Coercion** @@ -1492,7 +1492,7 @@ enum Direction { **Result Coercion** GraphQL services must return one of the defined set of possible values. If a -reasonable coercion is not possible they must raise a _runtime error_. +reasonable coercion is not possible they must raise an _execution error_. **Input Coercion** @@ -1654,9 +1654,9 @@ is constructed with the following rules: - If a variable is provided for an input object field, the runtime value of that variable must be used. If the runtime value is {null} and the field type is - non-null, a _runtime error_ must be raised. If no runtime value is provided, - the variable definition's default value should be used. If the variable - definition does not provide a default value, the input object field + non-null, an _execution error_ must be raised. If no runtime value is + provided, the variable definition's default value should be used. If the + variable definition does not provide a default value, the input object field definition's default value should be used. Following are examples of input coercion for an input object type with a @@ -1742,16 +1742,16 @@ brackets like this: `pets: [Pet]`. Nesting lists is allowed: `matrix: [[Int]]`. GraphQL services must return an ordered list as the result of a list type. Each item in the list must be the result of a result coercion of the item type. If a -reasonable coercion is not possible it must raise a _runtime error_. In +reasonable coercion is not possible it must raise an _execution error_. In particular, if a non-list is returned, the coercion should fail, as this indicates a mismatch in expectations between the type system and the implementation. If a list's item type is nullable, then errors occurring during preparation or coercion of an individual item in the list must result in a the value {null} at -that position in the list along with a _runtime error_ added to the response. If -a list's item type is non-null, a runtime error occurring at an individual item -in the list must result in a runtime error for the entire list. +that position in the list along with an _execution error_ added to the response. +If a list's item type is non-null, an execution error occurring at an individual +item in the list must result in an execution error for the entire list. Note: See [Handling Runtime Errors](#sec-Handling-Runtime-Errors) for more about this behavior. @@ -1812,10 +1812,10 @@ always optional and non-null types are always required. In all of the above result coercions, {null} was considered a valid value. To coerce the result of a Non-Null type, the coercion of the wrapped type should be performed. If that result was not {null}, then the result of coercing the -Non-Null type is that result. If that result was {null}, then a _runtime error_ -must be raised. +Non-Null type is that result. If that result was {null}, then an _execution +error_ must be raised. -Note: When a _runtime error_ is raised on a non-null _response position_, the +Note: When an _execution error_ is raised on a non-null _response position_, the error propagates to the parent _response position_. For more information on this process, see [Errors and Non-Null Types](#sec-Executing-Selection-Sets.Errors-and-Non-Null-Types) diff --git a/spec/Section 5 -- Validation.md b/spec/Section 5 -- Validation.md index 3ad186d1a..6ca9506d2 100644 --- a/spec/Section 5 -- Validation.md +++ b/spec/Section 5 -- Validation.md @@ -2010,4 +2010,4 @@ query booleanArgQueryWithDefault($booleanArg: Boolean = true) { ``` Note: The value {null} could still be provided to such a variable at runtime. A -non-null argument must raise a _runtime error_ if provided a {null} value. +non-null argument must raise an _execution error_ if provided a {null} value. diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 21b897a50..b4fabed98 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -137,7 +137,7 @@ ExecuteQuery(query, schema, variableValues, initialValue): - Let {data} be the result of running {ExecuteSelectionSet(selectionSet, queryType, initialValue, variableValues)} _normally_ (allowing parallelization). -- Let {errors} be the list of all _runtime error_ raised while executing the +- Let {errors} be the list of all _execution error_ raised while executing the selection set. - Return an unordered map containing {data} and {errors}. @@ -158,7 +158,7 @@ ExecuteMutation(mutation, schema, variableValues, initialValue): - Let {selectionSet} be the top level selection set in {mutation}. - Let {data} be the result of running {ExecuteSelectionSet(selectionSet, mutationType, initialValue, variableValues)} _serially_. -- Let {errors} be the list of all _runtime error_ raised while executing the +- Let {errors} be the list of all _execution error_ raised while executing the selection set. - Return an unordered map containing {data} and {errors}. @@ -317,7 +317,7 @@ MapSourceToResponseEvent(sourceStream, subscription, schema, variableValues): - Complete {responseStream} normally. - Return {responseStream}. -Note: Since {ExecuteSubscriptionEvent()} handles all _runtime error_, and +Note: Since {ExecuteSubscriptionEvent()} handles all _execution error_, and _request error_ only occur during {CreateSourceEventStream()}, the only remaining error condition handled from {ExecuteSubscriptionEvent()} are internal exceptional errors not described by this specification. @@ -330,7 +330,7 @@ ExecuteSubscriptionEvent(subscription, schema, variableValues, initialValue): - Let {data} be the result of running {ExecuteSelectionSet(selectionSet, subscriptionType, initialValue, variableValues)} _normally_ (allowing parallelization). -- Let {errors} be the list of all _runtime error_ raised while executing the +- Let {errors} be the list of all _execution error_ raised while executing the selection set. - Return an unordered map containing {data} and {errors}. @@ -384,10 +384,10 @@ is explained in greater detail in the Field Collection section below. **Errors and Non-Null Types** If during {ExecuteSelectionSet()} a _response position_ with a non-null type -raises a _runtime 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. +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. @@ -628,7 +628,7 @@ At each argument position in an operation may be a literal {Value}, or a {Variable} to be provided at runtime. Any _request error_ raised during {CoerceArgumentValues()} should be treated -instead as a _runtime error_. +instead as an _execution error_. CoerceArgumentValues(objectType, field, variableValues): @@ -656,7 +656,7 @@ CoerceArgumentValues(objectType, field, variableValues): - Add an entry to {coercedValues} named {argumentName} with the value {defaultValue}. - Otherwise if {argumentType} is a Non-Nullable type, and either {hasValue} is - not {true} or {value} is {null}, raise a _runtime error_. + not {true} or {value} is {null}, raise an _execution error_. - Otherwise if {hasValue} is {true}: - If {value} is {null}: - Add an entry to {coercedValues} named {argumentName} with the value @@ -666,7 +666,7 @@ CoerceArgumentValues(objectType, field, variableValues): {value}. - Otherwise: - If {value} cannot be coerced according to the input coercion rules of - {argumentType}, raise a _runtime error_. + {argumentType}, raise an _execution error_. - Let {coercedValue} be the result of coercing {value} according to the input coercion rules of {argumentType}. - Add an entry to {coercedValues} named {argumentName} with the value @@ -713,12 +713,12 @@ CompleteValue(fieldType, fields, result, variableValues): - Let {innerType} be the inner type of {fieldType}. - Let {completedResult} be the result of calling {CompleteValue(innerType, fields, result, variableValues)}. - - If {completedResult} is {null}, raise a _runtime error_. + - If {completedResult} is {null}, raise an _execution error_. - Return {completedResult}. - If {result} is {null} (or another internal value similar to {null} such as {undefined}), return {null}. - If {fieldType} is a List type: - - If {result} is not a collection of values, raise a _runtime error_. + - If {result} is not a collection of values, raise an _execution error_. - Let {innerType} be the inner type of {fieldType}. - Return a list where each list item is the result of calling {CompleteValue(innerType, fields, resultItem, variableValues)}, where @@ -753,7 +753,7 @@ CoerceResult(leafType, value): - Return the result of calling the internal method provided by the type system for determining the "result coercion" of {leafType} given the value {value}. This internal method must return a valid value for the type and not {null}. - Otherwise raise a _runtime error_. + Otherwise raise an _execution error_. Note: If a field resolver returns {null} then it is handled within {CompleteValue()} before {CoerceResult()} is called. Therefore both the input @@ -814,39 +814,39 @@ MergeSelectionSets(fields): ### Handling Runtime Errors -A _runtime error_ is an error raised from a particular field during value +An _execution error_ is an error raised from a particular field during value resolution or coercion. While these errors should be reported in the response, they are "handled" by producing a partial response. Note: This is distinct from a _request error_ which results in a response with no data. -If a runtime error is raised while resolving a field (either directly or nested -inside any lists), it is handled as though the position at which the error -occurred resulted in {null}, and the error must be added to the {"errors"} list -in the response. +If an execution error is raised while resolving a field (either directly or +nested inside any lists), it is handled as though the position at which the +error occurred resulted in {null}, and the error must be added to the {"errors"} +list in the response. If the result of resolving a _response position_ is {null} (either due to the -result of {ResolveFieldValue()} or because a runtime error was raised), and that -position is of a `Non-Null` type, then a runtime error is raised at that +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 response. -If a _response position_ returns {null} because of a runtime error which has +If a _response position_ returns {null} because of an execution error which has already been added to the {"errors"} list in the response, 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}, runtime errors are +Since `Non-Null` response positions cannot be {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 runtime error is further propagated to its parent _response -position_. +`Non-Null` type, the execution error is further propagated to its parent +_response position_. If a `List` type wraps a `Non-Null` type, and one of the elements of that list resolves to {null}, then the entire list must resolve to {null}. If the `List` -type is also wrapped in a `Non-Null`, the runtime error continues to propagate +type is also wrapped in a `Non-Null`, the execution error continues to propagate upwards. If all response positions from the root of the request to the source of the -runtime error return `Non-Null` types, then the {"data"} entry in the response +execution error return `Non-Null` types, then the {"data"} entry in the response should be {null}. diff --git a/spec/Section 7 -- Response.md b/spec/Section 7 -- Response.md index fbac9646d..f24fb717c 100644 --- a/spec/Section 7 -- Response.md +++ b/spec/Section 7 -- Response.md @@ -5,7 +5,7 @@ response. The service's response describes the result of executing the requested operation if successful, and describes any errors raised during the request. A response may contain both a partial response as well as a list of errors in -the case that any _runtime error_ was raised and replaced with {null}. +the case that any _execution error_ was raised and replaced with {null}. ## Response Format @@ -72,8 +72,8 @@ present. It must contain at least one _request error_ indicating why no data was able to be returned. If the `data` entry in the response is present (including if it is the value -{null}), the `errors` entry must be present if and only if one or more _runtime -error_ was raised during execution. +{null}), the `errors` entry must be present if and only if one or more +_execution error_ was raised during execution. **Request Errors** @@ -92,29 +92,29 @@ be halted. -**Runtime Errors** +**Execution Errors** -:: A _runtime error_ is an error raised during the execution of a particular +:: An _execution error_ is an error raised during the execution of a particular field which results in partial response data. This may occur due to failure to coerce the arguments for the field, an internal error during value resolution, -or failure to coerce the resulting value. A _runtime error_ may occur in any +or failure to coerce the resulting value. An _execution error_ may occur in any _response position_. -Note: In previous versions of this specification _runtime error_ was called +Note: In previous versions of this specification _execution error_ was called _field error_. :: A _response position_ is an identifiable position in the response: either a _field_, or a (potentially nested) list position within a field if the field has -a `List` type. A _runtime error_ may only occur within a _response position_. +a `List` type. An _execution error_ may only occur within a _response position_. The _response position_ is indicated in the _response_ via the error's _path entry_. -A runtime error is typically the fault of a GraphQL service. +An execution error is typically the fault of a GraphQL service. -If a runtime error is raised, execution attempts to continue and a partial +If an execution error is raised, execution attempts to continue and a partial result is produced (see -[Handling Runtime Errors](#sec-Handling-Runtime-Errors)). The `data` entry in -the response must be present. The `errors` entry must include this error. +[Handling Execution Errors](#sec-Handling-Execution-Errors)). The `data` entry +in the response must be present. The `errors` entry must include this error. **Error Result Format** From a4fe27e982e64b333cfe30280d1394201e96d636 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 27 Mar 2025 13:51:14 +0000 Subject: [PATCH 5/9] Oops, missed out these edits --- spec/Section 3 -- Type System.md | 4 ++-- spec/Section 6 -- Execution.md | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 0a865d08c..7c84da9be 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -1753,8 +1753,8 @@ that position in the list along with an _execution error_ added to the response. If a list's item type is non-null, an execution error occurring at an individual item in the list must result in an execution error for the entire list. -Note: See [Handling Runtime Errors](#sec-Handling-Runtime-Errors) for more about -this behavior. +Note: See [Handling Execution Errors](#sec-Handling-Execution-Errors) for more +about this behavior. **Input Coercion** diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index b4fabed98..077dbc8ec 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -392,8 +392,8 @@ 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. -Note: See [Handling Runtime Errors](#sec-Handling-Runtime-Errors) for more about -this behavior. +Note: See [Handling Execution Errors](#sec-Handling-Execution-Errors) for more +about this behavior. ### Normal and Serial Execution @@ -812,7 +812,7 @@ MergeSelectionSets(fields): -### Handling Runtime Errors +### Handling Execution Errors An _execution error_ is an error raised from a particular field during value resolution or coercion. While these errors should be reported in the response, From 920983277da43cb0df8d4db00546dbabbd03acbc Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 27 Mar 2025 13:50:16 +0000 Subject: [PATCH 6/9] Add error behaviors to the spec --- spec/Section 6 -- Execution.md | 98 +++++++++++++++++++++++++--------- spec/Section 7 -- Response.md | 6 +++ 2 files changed, 79 insertions(+), 25 deletions(-) diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 077dbc8ec..132111de1 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -15,10 +15,15 @@ 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. +- {errors} (optional): The _error behavior_ that is desired, see + [Handling Execution Errors](#sec-Handling-Execution-Errors). Given this information, the result of {ExecuteRequest(schema, document, operationName, variableValues, initialValue)} produces the response, to be -formatted according to the Response section below. +formatted according to the Response section below. The value of {errors} is +referenced by the [Handling Execution Errors](#sec-Handling-Execution-Errors) +section only, so we do not complicate the algorithms by passing it through every +call. Note: GraphQL requests do not require any specific serialization format or transport mechanism. Message serialization and transport mechanisms should be @@ -815,38 +820,81 @@ MergeSelectionSets(fields): ### Handling Execution Errors An _execution error_ is an error raised from a particular field during value -resolution or coercion. While these errors should be reported in the response, -they are "handled" by producing a partial response. +resolution or coercion. These errors should be reported in the response and are +"handled" according to the selected _error behavior_. -Note: This is distinct from a _request error_ which results in a response with -no data. +Note: An _execution error_ is distinct from a _request error_ which results in a +response with no data. -If an execution error is raised while resolving a field (either directly or -nested inside any lists), it is handled as though the position at which the -error occurred resulted in {null}, and the error must be added to the {"errors"} -list in the response. +If the result of resolving a field is {null}, and that field is of a `Non-Null` +type, then an execution error is raised by the field. -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 response. +If a `List` type wraps a `Non-Null` type, and one of the elements of that list +resolves to {null}, then an execution error is raised by the list item. + +:: The _error behavior_ is the way in which the request wishes for errors to be +handled. Valid values are {"PROPAGATE"}, {"NO_PROPAGATE"} and {"ABORT"}; their +respective behaviors are detailed below. + +Implementations are free to choose the default value to use if _error behavior_ +is not specified. It is recommended this is {"NO_PROPAGATE"} for newly created +schemas, but {"PROPAGATE"} should be used for existing schemas since that was +the implicit behavior in previous versions of this specification. + +Note: {"ABORT"} is not recommended as the default error behavior because it +makes clients less resilient to errors. GraphQL enables partial responses so +that the end user can still see some useful data even when something goes wrong +on the server. -If a _response position_ returns {null} because of an execution error which has +If an execution error is raised from a response position, it must be added to +the {"errors"} list in the _response_. + +If the response position returns {null} because of an execution error which has already been added to the {"errors"} list in the response, the {"errors"} list must not be further affected. That is, only one error should be added to the -errors list per _response position_. +errors list per response position. -Since `Non-Null` response positions cannot be {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 -_response position_. +Execution errors are handled according to the selected _error behavior_, as +detailed below: -If a `List` type wraps a `Non-Null` type, and one of the elements of that list -resolves to {null}, then the entire list must resolve to {null}. If the `List` -type is also wrapped in a `Non-Null`, the execution error continues to propagate -upwards. +**PROPAGATE** + +This is the traditional error handling approach in which errors are "handled" by +producing a partial response whilst ensuring that {null} may not occur in a +`Non-Null` position. + +If an execution error is raised while resolving a nullable response position, it +is handled as though the response position returned {null} (and as stated above, +the error must be added to the {"errors"} list in the response). + +Since `Non-Null` response positions cannot be {null}, execution errors that +occur in `Non-Null` response positions are propagated to be handled by the +parent 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 response position. If all response positions from the root of the request to the source of the execution error return `Non-Null` types, then the {"data"} entry in the response -should be {null}. +is made {null}. + +**NO_PROPAGATE** + +This is the modern error handling approach in which errors are "handled" by +producing a partial response _without_ propagating errors to conform to +`Non-Null` positions. + +Note: With this error behavior, the client is expected to honour the {"errors"} +in the _response_ and prevent developers from reading a {null} produced by an +error. One approach for clients to to prevent a {null} produced by an error from +being read is to raise an error on the client when the errored response +position's data is accessed. + +**ABORT** + +This error handling approach terminates the request when an execution error is +raised in any response position by setting the {"data"} entry in the response to +{null}. + +It is not recommended to default to {"ABORT"}, however it can be useful for +certain classes of clients, such as ad-hoc scripts, that do not know how to +handle errors and thus wish to abort and fail the moment any error occurs. diff --git a/spec/Section 7 -- Response.md b/spec/Section 7 -- Response.md index f24fb717c..0b6348ebd 100644 --- a/spec/Section 7 -- Response.md +++ b/spec/Section 7 -- Response.md @@ -26,6 +26,12 @@ key `data`. The value of this entry is described in the "Data" section. If the request failed before execution, due to a syntax error, missing information, or validation error, this entry must not be present. +If the request included execution, raised any errors, and the _error behavior_ +was not {"PROPAGATE"} then the response map must contain an entry with key +`errors`. Otherwise, inclusion of the `errors` key is permitted but not +recommended. The value of this key, if present, must be that of the _error +behavior_. + The response map may also contain an entry with key `extensions`. This entry, if set, must have a map as its value. This entry is reserved for implementers to extend the protocol however they see fit, and hence there are no additional From 9fee169010ef6a49774db656b9715c7e714a63e3 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 27 Mar 2025 15:42:30 +0000 Subject: [PATCH 7/9] Any execution may include onError --- spec/Section 6 -- Execution.md | 23 +++++++++++++++++------ spec/Section 7 -- Response.md | 7 ++++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 132111de1..9e796c488 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -15,15 +15,25 @@ 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. -- {errors} (optional): The _error behavior_ that is desired, see +- {onError} (optional): The _error behavior_ that is desired, see [Handling Execution Errors](#sec-Handling-Execution-Errors). Given this information, the result of {ExecuteRequest(schema, document, operationName, variableValues, initialValue)} produces the response, to be -formatted according to the Response section below. The value of {errors} is -referenced by the [Handling Execution Errors](#sec-Handling-Execution-Errors) -section only, so we do not complicate the algorithms by passing it through every -call. +formatted according to the Response section below. + +Servers should use the value of {onError}, if present, as the _error behavior_ +of the request described in +[Handling Execution Errors](#sec-Handling-Execution-Errors). However, it should +be noted that previous versions of this specification did not make this option +available and thus a client must not rely on the server to honor the {onError} +value it has specified. If a _response_ includes {"errors"}, the client must +check the {"onError"} of the _response_ determine how errors are treated. If no +such property is present, the client must treat the request as if it had +specified {onError} as {"PROPAGATE"}. + +If {onError} is present and it's value is not one of {"PROPAGATE"}, +{"NO_PROPAGATE"}, or {"ABORT"} then a request error must be raised. Note: GraphQL requests do not require any specific serialization format or transport mechanism. Message serialization and transport mechanisms should be @@ -833,7 +843,8 @@ If a `List` type wraps a `Non-Null` type, and one of the elements of that list resolves to {null}, then an execution error is raised by the list item. :: The _error behavior_ is the way in which the request wishes for errors to be -handled. Valid values are {"PROPAGATE"}, {"NO_PROPAGATE"} and {"ABORT"}; their +handled. It can be specified by the client using the {onError} property of the +_request_. Valid values are {"PROPAGATE"}, {"NO_PROPAGATE"} and {"ABORT"}; their respective behaviors are detailed below. Implementations are free to choose the default value to use if _error behavior_ diff --git a/spec/Section 7 -- Response.md b/spec/Section 7 -- Response.md index 0b6348ebd..1579b066c 100644 --- a/spec/Section 7 -- Response.md +++ b/spec/Section 7 -- Response.md @@ -28,9 +28,10 @@ validation error, this entry must not be present. If the request included execution, raised any errors, and the _error behavior_ was not {"PROPAGATE"} then the response map must contain an entry with key -`errors`. Otherwise, inclusion of the `errors` key is permitted but not -recommended. The value of this key, if present, must be that of the _error -behavior_. +`onError`. Otherwise if the request included execution, the server may include +the `onError` key. Otherwise, inclusion of the `onError` key is not recommended +(but is permitted). The value of this key, if present, must be that of the +_error behavior_. The response map may also contain an entry with key `extensions`. This entry, if set, must have a map as its value. This entry is reserved for implementers to From bd04f99a1e1c0aa2d906a30d6cb267b3aecff983 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 27 Mar 2025 17:19:24 +0000 Subject: [PATCH 8/9] Clearer wording, fix spelling --- spec/Section 6 -- Execution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 9e796c488..9f04b9c2b 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -897,8 +897,8 @@ producing a partial response _without_ propagating errors to conform to Note: With this error behavior, the client is expected to honour the {"errors"} in the _response_ and prevent developers from reading a {null} produced by an error. One approach for clients to to prevent a {null} produced by an error from -being read is to raise an error on the client when the errored response -position's data is accessed. +being read is to raise an error on the client when the data at that error's +_path entry_ is accessed. **ABORT** From 5f67e8d08ec40d118cc9af506d576a05fbfc92d6 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 27 Mar 2025 19:33:01 +0000 Subject: [PATCH 9/9] Minor edits --- spec/Section 6 -- Execution.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/Section 6 -- Execution.md b/spec/Section 6 -- Execution.md index 9f04b9c2b..72907a511 100644 --- a/spec/Section 6 -- Execution.md +++ b/spec/Section 6 -- Execution.md @@ -15,7 +15,7 @@ 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_ that is desired, see +- {onError} (optional, recommended): The _error behavior_ that is desired, see [Handling Execution Errors](#sec-Handling-Execution-Errors). Given this information, the result of {ExecuteRequest(schema, document, @@ -842,10 +842,10 @@ type, then an execution error is raised by the field. If a `List` type wraps a `Non-Null` type, and one of the elements of that list resolves to {null}, then an execution error is raised by the list item. -:: The _error behavior_ is the way in which the request wishes for errors to be -handled. It can be specified by the client using the {onError} property of the -_request_. Valid values are {"PROPAGATE"}, {"NO_PROPAGATE"} and {"ABORT"}; their -respective behaviors are detailed below. +:: The _error behavior_ indicates the way in which any errors are handled during +the request. It can be specified by the client using the {onError} property of +the _request_. Valid values are {"PROPAGATE"}, {"NO_PROPAGATE"} and {"ABORT"}; +their respective behaviors are detailed below. Implementations are free to choose the default value to use if _error behavior_ is not specified. It is recommended this is {"NO_PROPAGATE"} for newly created @@ -863,7 +863,7 @@ the {"errors"} list in the _response_. If the response position returns {null} because of an execution error which has already been added to the {"errors"} list in the response, the {"errors"} list must not be further affected. That is, only one error should be added to the -errors list per response position. +errors list per _response position_. Execution errors are handled according to the selected _error behavior_, as detailed below: