Allow to extend GraphQL errors with additional properties

ref: graphql/graphql-js#928
This commit is contained in:
Daniel Tschinder 2018-02-09 16:26:19 +01:00
parent 2cbccb87db
commit c4f11a577e
3 changed files with 48 additions and 2 deletions

View File

@ -73,6 +73,11 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
*/
protected $category;
/**
* @var array
*/
protected $extensions;
/**
* Given an arbitrary Error, presumably thrown while attempting to execute a
* GraphQL operation, produce a new GraphQLError aware of the location in the
@ -95,6 +100,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
}
$source = $positions = $originalError = null;
$extensions = [];
if ($error instanceof self) {
$message = $error->getMessage();
@ -102,6 +108,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
$nodes = $error->nodes ?: $nodes;
$source = $error->source;
$positions = $error->positions;
$extensions = $error->extensions;
} else if ($error instanceof \Exception || $error instanceof \Throwable) {
$message = $error->getMessage();
$originalError = $error;
@ -115,7 +122,8 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
$source,
$positions,
$path,
$originalError
$originalError,
$extensions
);
}
@ -136,6 +144,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
* @param array|null $positions
* @param array|null $path
* @param \Throwable $previous
* @param array $extensions
*/
public function __construct(
$message,
@ -143,7 +152,8 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
Source $source = null,
$positions = null,
$path = null,
$previous = null
$previous = null,
array $extensions = []
)
{
parent::__construct($message, 0, $previous);
@ -156,6 +166,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
$this->source = $source;
$this->positions = $positions;
$this->path = $path;
$this->extensions = $extensions;
if ($previous instanceof ClientAware) {
$this->isClientSafe = $previous->isClientSafe();
@ -260,6 +271,14 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
return $this->path;
}
/**
* @return array
*/
public function getExtensions()
{
return $this->extensions;
}
/**
* Returns array representation of error suitable for serialization
*
@ -272,6 +291,10 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
'message' => $this->getMessage()
];
if ($this->getExtensions()) {
$arr = array_merge($this->getExtensions(), $arr);
}
$locations = Utils::map($this->getLocations(), function(SourceLocation $loc) {
return $loc->toSerializableArray();
});

View File

@ -66,6 +66,10 @@ class FormattedError
}
if ($e instanceof Error) {
if ($e->getExtensions()) {
$formattedError = array_merge($e->getExtensions(), $formattedError);
}
$locations = Utils::map($e->getLocations(), function(SourceLocation $loc) {
return $loc->toSerializableArray();
});

View File

@ -110,4 +110,23 @@ class ErrorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals([ 'path', 3, 'to', 'field' ], $e->path);
$this->assertEquals(['message' => 'msg', 'path' => [ 'path', 3, 'to', 'field' ]], $e->toSerializableArray());
}
/**
* @it default error formatter includes extension fields
*/
public function testDefaultErrorFormatterIncludesExtensionFields()
{
$e = new Error(
'msg',
null,
null,
null,
null,
null,
['foo' => 'bar']
);
$this->assertEquals(['foo' => 'bar'], $e->getExtensions());
$this->assertEquals(['message' => 'msg', 'foo' => 'bar'], $e->toSerializableArray());
}
}