mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-22 12:56:05 +03:00
Default Error Formatting: Display error category
under extensions
key (#389)
This commit is contained in:
parent
54263d50c0
commit
c45fa1a4b1
@ -10,7 +10,7 @@ It is a one-line switch: `GraphQL::useExperimentalExecutor()`.<br>
|
|||||||
(as it may become the default one in future)
|
(as it may become the default one in future)
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
- 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`)
|
- `AbstractValidationRule` renamed to `ValidationRule` (NS `GraphQL\Validator\Rules`)
|
||||||
- `AbstractQuerySecurity` renamed to `QuerySecurityRule` (NS `GraphQL\Validator\Rules`)
|
- `AbstractQuerySecurity` renamed to `QuerySecurityRule` (NS `GraphQL\Validator\Rules`)
|
||||||
- `FindBreakingChanges` renamed to `BreakingChangesFinder` (NS `GraphQL\Utils`)
|
- `FindBreakingChanges` renamed to `BreakingChangesFinder` (NS `GraphQL\Utils`)
|
||||||
|
74
UPGRADE.md
74
UPGRADE.md
@ -1,39 +1,10 @@
|
|||||||
## Upgrade v0.12.x > dev-master
|
## Upgrade v0.12.x > dev-master
|
||||||
|
|
||||||
### Try it: Experimental Executor with improved performance
|
### Breaking (major): minimum supported version of PHP
|
||||||
It is disabled by default. To enable it, do the following
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
use GraphQL\Executor\Executor;
|
|
||||||
use GraphQL\Experimental\Executor\CoroutineExecutor;
|
|
||||||
|
|
||||||
Executor::setImplementationFactory([CoroutineExecutor::class, 'create']);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Please post your feedback about new executor at https://github.com/webonyx/graphql-php/issues/397
|
|
||||||
Especially if you had issues (because it may become the default in one of the next releases)**
|
|
||||||
|
|
||||||
### Breaking: minimum supported version of PHP
|
|
||||||
New minimum required version of PHP is **7.1+**
|
New minimum required version of PHP is **7.1+**
|
||||||
|
|
||||||
### Breaking: multiple interfaces separated with & in SDL
|
### Breaking (major): default errors formatting changed according to spec
|
||||||
Before the change:
|
**Category** and extensions assigned to errors are shown under `extensions` key
|
||||||
```graphql
|
|
||||||
type Foo implements Bar, Baz { field: Type }
|
|
||||||
```
|
|
||||||
|
|
||||||
After the change:
|
|
||||||
```graphql
|
|
||||||
type Foo implements Bar & Baz { field: Type }
|
|
||||||
```
|
|
||||||
|
|
||||||
To allow for an adaptive migration, use `allowLegacySDLImplementsInterfaces` option of parser:
|
|
||||||
```php
|
|
||||||
Parser::parse($source, [ 'allowLegacySDLImplementsInterfaces' => true])
|
|
||||||
```
|
|
||||||
|
|
||||||
### Breaking: errors formatting changed according to spec
|
|
||||||
Extensions assigned to errors are shown under `extensions` key
|
|
||||||
```php
|
```php
|
||||||
$e = new Error(
|
$e = new Error(
|
||||||
'msg',
|
'msg',
|
||||||
@ -50,6 +21,7 @@ Formatting before the change:
|
|||||||
'errors' => [
|
'errors' => [
|
||||||
[
|
[
|
||||||
'message' => 'msg',
|
'message' => 'msg',
|
||||||
|
'category' => 'graphql',
|
||||||
'foo' => 'bar'
|
'foo' => 'bar'
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -59,11 +31,47 @@ After the change:
|
|||||||
'errors' => [
|
'errors' => [
|
||||||
[
|
[
|
||||||
'message' => 'msg',
|
'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
|
||||||
|
<?php
|
||||||
|
use GraphQL\Executor\Executor;
|
||||||
|
use GraphQL\Experimental\Executor\CoroutineExecutor;
|
||||||
|
|
||||||
|
Executor::setImplementationFactory([CoroutineExecutor::class, 'create']);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Please post your feedback about new executor at https://github.com/webonyx/graphql-php/issues/397
|
||||||
|
Especially if you had issues (because it may become the default in one of the next releases)**
|
||||||
|
|
||||||
|
### Breaking: multiple interfaces separated with & in SDL
|
||||||
|
Before the change:
|
||||||
|
```graphql
|
||||||
|
type Foo implements Bar, Baz { field: Type }
|
||||||
|
```
|
||||||
|
|
||||||
|
After the change:
|
||||||
|
```graphql
|
||||||
|
type Foo implements Bar & Baz { field: Type }
|
||||||
|
```
|
||||||
|
|
||||||
|
To allow for an adaptive migration, use `allowLegacySDLImplementsInterfaces` option of parser:
|
||||||
|
```php
|
||||||
|
Parser::parse($source, [ 'allowLegacySDLImplementsInterfaces' => true])
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Upgrade v0.11.x > v0.12.x
|
## Upgrade v0.11.x > v0.12.x
|
||||||
|
|
||||||
|
@ -187,12 +187,16 @@ class FormattedError
|
|||||||
if ($e instanceof ClientAware) {
|
if ($e instanceof ClientAware) {
|
||||||
$formattedError = [
|
$formattedError = [
|
||||||
'message' => $e->isClientSafe() ? $e->getMessage() : $internalErrorMessage,
|
'message' => $e->isClientSafe() ? $e->getMessage() : $internalErrorMessage,
|
||||||
|
'extensions' => [
|
||||||
'category' => $e->getCategory(),
|
'category' => $e->getCategory(),
|
||||||
|
],
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
$formattedError = [
|
$formattedError = [
|
||||||
'message' => $internalErrorMessage,
|
'message' => $internalErrorMessage,
|
||||||
|
'extensions' => [
|
||||||
'category' => Error::CATEGORY_INTERNAL,
|
'category' => Error::CATEGORY_INTERNAL,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +214,7 @@ class FormattedError
|
|||||||
$formattedError['path'] = $e->path;
|
$formattedError['path'] = $e->path;
|
||||||
}
|
}
|
||||||
if (! empty($e->getExtensions())) {
|
if (! empty($e->getExtensions())) {
|
||||||
$formattedError['extensions'] = $e->getExtensions();
|
$formattedError['extensions'] = $e->getExtensions() + $formattedError['extensions'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ class AbstractTest extends TestCase
|
|||||||
'function or each possible type should provide an "isTypeOf" function.',
|
'function or each possible type should provide an "isTypeOf" function.',
|
||||||
'locations' => [['line' => 1, 'column' => 3]],
|
'locations' => [['line' => 1, 'column' => 3]],
|
||||||
'path' => ['foo'],
|
'path' => ['foo'],
|
||||||
'category' => 'internal',
|
'extensions' => ['category' => 'internal'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -222,7 +222,7 @@ class VariablesTest extends TestCase
|
|||||||
'{"a":"foo","b":"bar","c":null}; ' .
|
'{"a":"foo","b":"bar","c":null}; ' .
|
||||||
'Expected non-nullable type String! not to be null at value.c.',
|
'Expected non-nullable type String! not to be null at value.c.',
|
||||||
'locations' => [['line' => 2, 'column' => 21]],
|
'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"; ' .
|
'Variable "$input" got invalid value "foo bar"; ' .
|
||||||
'Expected type TestInputObject to be an object.',
|
'Expected type TestInputObject to be an object.',
|
||||||
'locations' => [['line' => 2, 'column' => 21]],
|
'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"}; ' .
|
'Variable "$input" got invalid value {"a":"foo","b":"bar"}; ' .
|
||||||
'Field value.c of required type String! was not provided.',
|
'Field value.c of required type String! was not provided.',
|
||||||
'locations' => [['line' => 2, 'column' => 21]],
|
'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"}}; ' .
|
'Variable "$input" got invalid value {"na":{"a":"foo"}}; ' .
|
||||||
'Field value.na.c of required type String! was not provided.',
|
'Field value.na.c of required type String! was not provided.',
|
||||||
'locations' => [['line' => 2, 'column' => 19]],
|
'locations' => [['line' => 2, 'column' => 19]],
|
||||||
'category' => 'graphql',
|
'extensions' => ['category' => 'graphql'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'message' =>
|
'message' =>
|
||||||
'Variable "$input" got invalid value {"na":{"a":"foo"}}; ' .
|
'Variable "$input" got invalid value {"na":{"a":"foo"}}; ' .
|
||||||
'Field value.nb of required type String! was not provided.',
|
'Field value.nb of required type String! was not provided.',
|
||||||
'locations' => [['line' => 2, 'column' => 19]],
|
'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"}; ' .
|
'{"a":"foo","b":"bar","c":"baz","extra":"dog"}; ' .
|
||||||
'Field "extra" is not defined by type TestInputObject.',
|
'Field "extra" is not defined by type TestInputObject.',
|
||||||
'locations' => [['line' => 2, 'column' => 21]],
|
'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.',
|
'message' => 'Variable "$value" of required type "String!" was not provided.',
|
||||||
'locations' => [['line' => 2, 'column' => 31]],
|
'locations' => [['line' => 2, 'column' => 31]],
|
||||||
'category' => 'graphql',
|
'extensions' => ['category' => 'graphql'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@ -459,7 +459,7 @@ class VariablesTest extends TestCase
|
|||||||
'Variable "$value" got invalid value null; ' .
|
'Variable "$value" got invalid value null; ' .
|
||||||
'Expected non-nullable type String! not to be null.',
|
'Expected non-nullable type String! not to be null.',
|
||||||
'locations' => [['line' => 2, 'column' => 31]],
|
'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.',
|
'message' => 'Argument "input" of required type "String!" was not provided.',
|
||||||
'locations' => [['line' => 3, 'column' => 9]],
|
'locations' => [['line' => 3, 'column' => 9]],
|
||||||
'path' => ['fieldWithNonNullableStringInput'],
|
'path' => ['fieldWithNonNullableStringInput'],
|
||||||
'category' => 'graphql',
|
'extensions' => ['category' => 'graphql'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@ -538,10 +538,10 @@ class VariablesTest extends TestCase
|
|||||||
'message' =>
|
'message' =>
|
||||||
'Variable "$value" got invalid value [1,2,3]; Expected type ' .
|
'Variable "$value" got invalid value [1,2,3]; Expected type ' .
|
||||||
'String; String cannot represent an array value: [1,2,3]',
|
'String; String cannot represent an array value: [1,2,3]',
|
||||||
'category' => 'graphql',
|
|
||||||
'locations' => [
|
'locations' => [
|
||||||
['line' => 2, 'column' => 31],
|
['line' => 2, 'column' => 31],
|
||||||
],
|
],
|
||||||
|
'extensions' => ['category' => 'graphql'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@ -581,7 +581,7 @@ class VariablesTest extends TestCase
|
|||||||
'variable "$foo" which was not provided a runtime value.',
|
'variable "$foo" which was not provided a runtime value.',
|
||||||
'locations' => [['line' => 3, 'column' => 48]],
|
'locations' => [['line' => 3, 'column' => 48]],
|
||||||
'path' => ['fieldWithNonNullableStringInput'],
|
'path' => ['fieldWithNonNullableStringInput'],
|
||||||
'category' => 'graphql',
|
'extensions' => ['category' => 'graphql'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@ -652,7 +652,7 @@ class VariablesTest extends TestCase
|
|||||||
'Variable "$input" got invalid value null; ' .
|
'Variable "$input" got invalid value null; ' .
|
||||||
'Expected non-nullable type [String]! not to be null.',
|
'Expected non-nullable type [String]! not to be null.',
|
||||||
'locations' => [['line' => 2, 'column' => 17]],
|
'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"]; ' .
|
'Variable "$input" got invalid value ["A",null,"B"]; ' .
|
||||||
'Expected non-nullable type String! not to be null at value[1].',
|
'Expected non-nullable type String! not to be null at value[1].',
|
||||||
'locations' => [['line' => 2, 'column' => 17]],
|
'locations' => [['line' => 2, 'column' => 17]],
|
||||||
'category' => 'graphql',
|
'extensions' => ['category' => 'graphql'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@ -762,7 +762,7 @@ class VariablesTest extends TestCase
|
|||||||
'Variable "$input" got invalid value null; ' .
|
'Variable "$input" got invalid value null; ' .
|
||||||
'Expected non-nullable type [String!]! not to be null.',
|
'Expected non-nullable type [String!]! not to be null.',
|
||||||
'locations' => [['line' => 2, 'column' => 17]],
|
'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"]; ' .
|
'Variable "$input" got invalid value ["A",null,"B"]; ' .
|
||||||
'Expected non-nullable type String! not to be null at value[1].',
|
'Expected non-nullable type String! not to be null at value[1].',
|
||||||
'locations' => [['line' => 2, 'column' => 17]],
|
'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 ' .
|
'Variable "$input" expected value of type "TestType!" which cannot ' .
|
||||||
'be used as an input type.',
|
'be used as an input type.',
|
||||||
'locations' => [['line' => 2, 'column' => 25]],
|
'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 ' .
|
'Variable "$input" expected value of type "UnknownType!" which ' .
|
||||||
'cannot be used as an input type.',
|
'cannot be used as an input type.',
|
||||||
'locations' => [['line' => 2, 'column' => 25]],
|
'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.',
|
'Argument "input" has invalid value WRONG_TYPE.',
|
||||||
'locations' => [['line' => 2, 'column' => 50]],
|
'locations' => [['line' => 2, 'column' => 50]],
|
||||||
'path' => ['fieldWithDefaultArgumentValue'],
|
'path' => ['fieldWithDefaultArgumentValue'],
|
||||||
'category' => 'graphql',
|
'extensions' => ['category' => 'graphql'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -260,7 +260,7 @@ class QueryExecutionTest extends ServerTestCase
|
|||||||
'errors' => [
|
'errors' => [
|
||||||
[
|
[
|
||||||
'message' => 'Persisted queries are not supported by this server',
|
'message' => 'Persisted queries are not supported by this server',
|
||||||
'category' => 'request',
|
'extensions' => ['category' => 'request'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@ -291,7 +291,7 @@ class QueryExecutionTest extends ServerTestCase
|
|||||||
'errors' => [
|
'errors' => [
|
||||||
[
|
[
|
||||||
'message' => 'Batched queries are not supported by this server',
|
'message' => 'Batched queries are not supported by this server',
|
||||||
'category' => 'request',
|
'extensions' => ['category' => 'request'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -299,7 +299,7 @@ class QueryExecutionTest extends ServerTestCase
|
|||||||
'errors' => [
|
'errors' => [
|
||||||
[
|
[
|
||||||
'message' => 'Batched queries are not supported by this server',
|
'message' => 'Batched queries are not supported by this server',
|
||||||
'category' => 'request',
|
'extensions' => ['category' => 'request'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -342,7 +342,7 @@ class QueryExecutionTest extends ServerTestCase
|
|||||||
'errors' => [
|
'errors' => [
|
||||||
[
|
[
|
||||||
'message' => 'GET supports only query operation',
|
'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".',
|
'message' => 'Cannot query field "invalid" on type "Query".',
|
||||||
'locations' => [['line' => 1, 'column' => 2]],
|
'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".',
|
'message' => 'Cannot query field "invalid2" on type "Query".',
|
||||||
'locations' => [['line' => 1, 'column' => 2]],
|
'locations' => [['line' => 1, 'column' => 2]],
|
||||||
'category' => 'graphql',
|
'extensions' => ['category' => 'graphql'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
Loading…
Reference in New Issue
Block a user