Skip to content

Commit 0f515b8

Browse files
living42Mikk Mihkel Nurges
authored andcommitted
Fix #161 (#163)
* Using the default formatError function from graphql-php * Fix tests * Passing errors through laravel's Error Handling mechanism
1 parent 0151c33 commit 0f515b8

File tree

4 files changed

+39
-30
lines changed

4 files changed

+39
-30
lines changed

src/Rebing/GraphQL/GraphQL.php

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
<?php namespace Rebing\GraphQL;
22

3+
use GraphQL\Error\Debug;
34
use GraphQL\Error\Error;
45
use Rebing\GraphQL\Error\ValidationError;
56
use GraphQL\GraphQL as GraphQLBase;
67
use GraphQL\Type\Schema;
8+
use GraphQL\Error\FormattedError;
79
use GraphQL\Type\Definition\ObjectType;
810
use Rebing\GraphQL\Exception\SchemaNotFound;
911
use Rebing\GraphQL\Support\PaginationType;
12+
use Illuminate\Contracts\Debug\ExceptionHandler;
1013

1114
class GraphQL {
1215
protected $app;
@@ -84,21 +87,7 @@ public function schema($schema = null)
8487
*/
8588
public function query($query, $params = [], $opts = [])
8689
{
87-
$executionResult = $this->queryAndReturnResult($query, $params, $opts);
88-
89-
$data = [
90-
'data' => $executionResult->data,
91-
];
92-
93-
// Add errors
94-
if( ! empty($executionResult->errors))
95-
{
96-
$errorFormatter = config('graphql.error_formatter', ['\Rebing\GraphQL', 'formatError']);
97-
98-
$data['errors'] = array_map($errorFormatter, $executionResult->errors);
99-
}
100-
101-
return $data;
90+
return $this->queryAndReturnResult($query, $params, $opts)->toArray();
10291
}
10392

10493
public function queryAndReturnResult($query, $params = [], $opts = [])
@@ -109,7 +98,12 @@ public function queryAndReturnResult($query, $params = [], $opts = [])
10998

11099
$schema = $this->schema($schemaName);
111100

112-
$result = GraphQLBase::executeQuery($schema, $query, null, $context, $params, $operationName);
101+
$errorFormatter = config('graphql.error_formatter', [static::class, 'formatError']);
102+
$errorsHandler = config('grahpql.errors_handler', [static::class, 'handleErrors']);
103+
104+
$result = GraphQLBase::executeQuery($schema, $query, null, $context, $params, $operationName)
105+
->setErrorsHandler($errorsHandler)
106+
->setErrorFormatter($errorFormatter);
113107
return $result;
114108
}
115109

@@ -282,18 +276,9 @@ public function paginate($typeName, $customName = null)
282276

283277
public static function formatError(Error $e)
284278
{
285-
$error = [
286-
'message' => $e->getMessage()
287-
];
288-
289-
$locations = $e->getLocations();
290-
if(!empty($locations))
291-
{
292-
$error['locations'] = array_map(function($loc)
293-
{
294-
return $loc->toArray();
295-
}, $locations);
296-
}
279+
$debug = config('app.debug') ? (Debug::INCLUDE_DEBUG_MESSAGE | Debug::INCLUDE_TRACE) : 0;
280+
$formatter = FormattedError::prepareFormatter(null, $debug);
281+
$error = $formatter($e);
297282

298283
$previous = $e->getPrevious();
299284
if($previous && $previous instanceof ValidationError)
@@ -304,6 +289,20 @@ public static function formatError(Error $e)
304289
return $error;
305290
}
306291

292+
public static function handleErrors(array $errors, callable $formatter)
293+
{
294+
$handler = app()->make(ExceptionHandler::class);
295+
foreach ($errors as $error) {
296+
// Try to unwrap exception
297+
$error = $error->getPrevious() ?: $error;
298+
if ($error instanceof \GraphQL\Error\Error) {
299+
continue;
300+
}
301+
$handler->report($error);
302+
}
303+
return array_map($formatter, $errors);
304+
}
305+
307306
/**
308307
* Check if the schema expects a nest URI name and return the formatted version
309308
* Eg. 'user/me'

src/config/config.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@
133133
// ]
134134
'error_formatter' => ['\Rebing\GraphQL\GraphQL', 'formatError'],
135135

136+
/**
137+
* Custom Error Handling
138+
*
139+
* Expected handler signature is: function (array $errors, callable $formatter): array
140+
*
141+
* The default handler will pass exceptions to laravel Error Handling mechanism
142+
*/
143+
'errors_handler' => ['\Rebing\GraphQL\GraphQL', 'handleErrors'],
144+
136145
// You can set the key, which will be used to retrieve the dynamic variables
137146
'params_key' => 'variables',
138147

tests/GraphQLQueryTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,15 @@ public function testQueryAndReturnResultWithSchema()
9696
/**
9797
* Test query with error
9898
*
99+
* If an error was encountered before execution begins, the data entry should not be present in the result.
100+
*
99101
* @test
100102
*/
101103
public function testQueryWithError()
102104
{
103105
$result = GraphQL::query($this->queries['examplesWithError']);
104106

105-
$this->assertArrayHasKey('data', $result);
106107
$this->assertArrayHasKey('errors', $result);
107-
$this->assertNull($result['data']);
108108
$this->assertCount(1, $result['errors']);
109109
$this->assertArrayHasKey('message', $result['errors'][0]);
110110
$this->assertArrayHasKey('locations', $result['errors'][0]);

tests/GraphQLTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ public function testFormatError()
183183
$this->assertArrayHasKey('locations', $error);
184184
$this->assertEquals($error, [
185185
'message' => 'Cannot query field "examplesQueryNotFound" on type "Query".',
186+
'category' => 'graphql',
186187
'locations' => [
187188
[
188189
'line' => 3,

0 commit comments

Comments
 (0)