diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e28429..4d650ed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,7 +10,7 @@ It is a one-line switch: `GraphQL::useExperimentalExecutor()`.
(as it may become the default one in future)
-- Spec compliance: error category, debug information and extensions are displayed under `extensions` key
+- Spec compliance: error `category` and extensions are displayed under `extensions` key when using default formatting (#389)
- `AbstractValidationRule` renamed to `ValidationRule` (NS `GraphQL\Validator\Rules`)
- `AbstractQuerySecurity` renamed to `QuerySecurityRule` (NS `GraphQL\Validator\Rules`)
- `FindBreakingChanges` renamed to `BreakingChangesFinder` (NS `GraphQL\Utils`)
diff --git a/UPGRADE.md b/UPGRADE.md
index b560ce1..cebfb03 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -1,39 +1,10 @@
## Upgrade v0.12.x > dev-master
-### Try it: Experimental Executor with improved performance
-It is disabled by default. To enable it, do the following
-```php
- true])
-```
-
-### Breaking: errors formatting changed according to spec
-Extensions assigned to errors are shown under `extensions` key
+### Breaking (major): default errors formatting changed according to spec
+**Category** and extensions assigned to errors are shown under `extensions` key
```php
$e = new Error(
'msg',
@@ -50,6 +21,7 @@ Formatting before the change:
'errors' => [
[
'message' => 'msg',
+ 'category' => 'graphql',
'foo' => 'bar'
]
]
@@ -59,11 +31,47 @@ After the change:
'errors' => [
[
'message' => 'msg',
- 'extensions' => ['foo' => 'bar'],
+ 'extensions' => [
+ 'category' => 'graphql',
+ 'foo' => 'bar',
+ ],
]
]
```
+Note: if error extensions contain `category` key - it has a priority over default category.
+
+You can always switch to [custom error formatting](https://webonyx.github.io/graphql-php/error-handling/#custom-error-handling-and-formatting) to revert to the old format.
+
+### Try it: Experimental Executor with improved performance
+It is disabled by default. To enable it, do the following
+```php
+ true])
+```
+
## Upgrade v0.11.x > v0.12.x
diff --git a/src/Error/FormattedError.php b/src/Error/FormattedError.php
index e03b2ac..b200774 100644
--- a/src/Error/FormattedError.php
+++ b/src/Error/FormattedError.php
@@ -187,12 +187,16 @@ class FormattedError
if ($e instanceof ClientAware) {
$formattedError = [
'message' => $e->isClientSafe() ? $e->getMessage() : $internalErrorMessage,
- 'category' => $e->getCategory(),
+ 'extensions' => [
+ 'category' => $e->getCategory(),
+ ],
];
} else {
$formattedError = [
'message' => $internalErrorMessage,
- 'category' => Error::CATEGORY_INTERNAL,
+ 'extensions' => [
+ 'category' => Error::CATEGORY_INTERNAL,
+ ],
];
}
@@ -210,7 +214,7 @@ class FormattedError
$formattedError['path'] = $e->path;
}
if (! empty($e->getExtensions())) {
- $formattedError['extensions'] = $e->getExtensions();
+ $formattedError['extensions'] = $e->getExtensions() + $formattedError['extensions'];
}
}
diff --git a/tests/Executor/AbstractTest.php b/tests/Executor/AbstractTest.php
index a1423b9..eba24ec 100644
--- a/tests/Executor/AbstractTest.php
+++ b/tests/Executor/AbstractTest.php
@@ -420,7 +420,7 @@ class AbstractTest extends TestCase
'function or each possible type should provide an "isTypeOf" function.',
'locations' => [['line' => 1, 'column' => 3]],
'path' => ['foo'],
- 'category' => 'internal',
+ 'extensions' => ['category' => 'internal'],
],
],
];
diff --git a/tests/Executor/VariablesTest.php b/tests/Executor/VariablesTest.php
index 0751c67..c2625ae 100644
--- a/tests/Executor/VariablesTest.php
+++ b/tests/Executor/VariablesTest.php
@@ -222,7 +222,7 @@ class VariablesTest extends TestCase
'{"a":"foo","b":"bar","c":null}; ' .
'Expected non-nullable type String! not to be null at value.c.',
'locations' => [['line' => 2, 'column' => 21]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -239,7 +239,7 @@ class VariablesTest extends TestCase
'Variable "$input" got invalid value "foo bar"; ' .
'Expected type TestInputObject to be an object.',
'locations' => [['line' => 2, 'column' => 21]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -256,7 +256,7 @@ class VariablesTest extends TestCase
'Variable "$input" got invalid value {"a":"foo","b":"bar"}; ' .
'Field value.c of required type String! was not provided.',
'locations' => [['line' => 2, 'column' => 21]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -278,14 +278,14 @@ class VariablesTest extends TestCase
'Variable "$input" got invalid value {"na":{"a":"foo"}}; ' .
'Field value.na.c of required type String! was not provided.',
'locations' => [['line' => 2, 'column' => 19]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
[
'message' =>
'Variable "$input" got invalid value {"na":{"a":"foo"}}; ' .
'Field value.nb of required type String! was not provided.',
'locations' => [['line' => 2, 'column' => 19]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -302,7 +302,7 @@ class VariablesTest extends TestCase
'{"a":"foo","b":"bar","c":"baz","extra":"dog"}; ' .
'Field "extra" is not defined by type TestInputObject.',
'locations' => [['line' => 2, 'column' => 21]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -434,7 +434,7 @@ class VariablesTest extends TestCase
[
'message' => 'Variable "$value" of required type "String!" was not provided.',
'locations' => [['line' => 2, 'column' => 31]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -459,7 +459,7 @@ class VariablesTest extends TestCase
'Variable "$value" got invalid value null; ' .
'Expected non-nullable type String! not to be null.',
'locations' => [['line' => 2, 'column' => 31]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -511,7 +511,7 @@ class VariablesTest extends TestCase
'message' => 'Argument "input" of required type "String!" was not provided.',
'locations' => [['line' => 3, 'column' => 9]],
'path' => ['fieldWithNonNullableStringInput'],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -538,10 +538,10 @@ class VariablesTest extends TestCase
'message' =>
'Variable "$value" got invalid value [1,2,3]; Expected type ' .
'String; String cannot represent an array value: [1,2,3]',
- 'category' => 'graphql',
'locations' => [
['line' => 2, 'column' => 31],
],
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -581,7 +581,7 @@ class VariablesTest extends TestCase
'variable "$foo" which was not provided a runtime value.',
'locations' => [['line' => 3, 'column' => 48]],
'path' => ['fieldWithNonNullableStringInput'],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -652,7 +652,7 @@ class VariablesTest extends TestCase
'Variable "$input" got invalid value null; ' .
'Expected non-nullable type [String]! not to be null.',
'locations' => [['line' => 2, 'column' => 17]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -737,7 +737,7 @@ class VariablesTest extends TestCase
'Variable "$input" got invalid value ["A",null,"B"]; ' .
'Expected non-nullable type String! not to be null at value[1].',
'locations' => [['line' => 2, 'column' => 17]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -762,7 +762,7 @@ class VariablesTest extends TestCase
'Variable "$input" got invalid value null; ' .
'Expected non-nullable type [String!]! not to be null.',
'locations' => [['line' => 2, 'column' => 17]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -804,7 +804,7 @@ class VariablesTest extends TestCase
'Variable "$input" got invalid value ["A",null,"B"]; ' .
'Expected non-nullable type String! not to be null at value[1].',
'locations' => [['line' => 2, 'column' => 17]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -830,7 +830,7 @@ class VariablesTest extends TestCase
'Variable "$input" expected value of type "TestType!" which cannot ' .
'be used as an input type.',
'locations' => [['line' => 2, 'column' => 25]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -857,7 +857,7 @@ class VariablesTest extends TestCase
'Variable "$input" expected value of type "UnknownType!" which ' .
'cannot be used as an input type.',
'locations' => [['line' => 2, 'column' => 25]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -910,7 +910,7 @@ class VariablesTest extends TestCase
'Argument "input" has invalid value WRONG_TYPE.',
'locations' => [['line' => 2, 'column' => 50]],
'path' => ['fieldWithDefaultArgumentValue'],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
diff --git a/tests/Server/QueryExecutionTest.php b/tests/Server/QueryExecutionTest.php
index fffa9b8..bc16ed6 100644
--- a/tests/Server/QueryExecutionTest.php
+++ b/tests/Server/QueryExecutionTest.php
@@ -260,7 +260,7 @@ class QueryExecutionTest extends ServerTestCase
'errors' => [
[
'message' => 'Persisted queries are not supported by this server',
- 'category' => 'request',
+ 'extensions' => ['category' => 'request'],
],
],
];
@@ -291,7 +291,7 @@ class QueryExecutionTest extends ServerTestCase
'errors' => [
[
'message' => 'Batched queries are not supported by this server',
- 'category' => 'request',
+ 'extensions' => ['category' => 'request'],
],
],
],
@@ -299,7 +299,7 @@ class QueryExecutionTest extends ServerTestCase
'errors' => [
[
'message' => 'Batched queries are not supported by this server',
- 'category' => 'request',
+ 'extensions' => ['category' => 'request'],
],
],
],
@@ -342,7 +342,7 @@ class QueryExecutionTest extends ServerTestCase
'errors' => [
[
'message' => 'GET supports only query operation',
- 'category' => 'request',
+ 'extensions' => ['category' => 'request'],
],
],
];
@@ -406,7 +406,7 @@ class QueryExecutionTest extends ServerTestCase
[
'message' => 'Cannot query field "invalid" on type "Query".',
'locations' => [['line' => 1, 'column' => 2]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];
@@ -443,7 +443,7 @@ class QueryExecutionTest extends ServerTestCase
[
'message' => 'Cannot query field "invalid2" on type "Query".',
'locations' => [['line' => 1, 'column' => 2]],
- 'category' => 'graphql',
+ 'extensions' => ['category' => 'graphql'],
],
],
];