From 173fb4fd448ed56d7d18c6d0c76c50ec1bc64831 Mon Sep 17 00:00:00 2001 From: spawnia Date: Sun, 15 Mar 2020 19:36:39 +0100 Subject: [PATCH 01/13] Add test to specify what happens on failed delete --- src/Schema/Directives/DeleteDirective.php | 8 +++- .../Schema/Directives/DeleteDirectiveTest.php | 42 +++++++++++++++++-- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/Schema/Directives/DeleteDirective.php b/src/Schema/Directives/DeleteDirective.php index 9263c67a0d..0c63905b7a 100644 --- a/src/Schema/Directives/DeleteDirective.php +++ b/src/Schema/Directives/DeleteDirective.php @@ -2,6 +2,7 @@ namespace Nuwave\Lighthouse\Schema\Directives; +use GraphQL\Error\Error; use GraphQL\Language\AST\FieldDefinitionNode; use GraphQL\Language\AST\InputValueDefinitionNode; use GraphQL\Language\AST\ObjectTypeDefinitionNode; @@ -48,6 +49,11 @@ public static function definition(): string SDL; } + public static function couldNotDelete(Model $user): string + { + return 'Could not delete model ' . get_class($user) . ' with ID ' . $user->getKey() . '.'; + } + /** * Find one or more models by id. * @@ -100,8 +106,6 @@ public function __invoke($parent, $idOrIds): void $relation->dissociate(); $relation->getParent()->save(); } - - $relation->delete(); } } else { $related = $relation->make(); diff --git a/tests/Integration/Schema/Directives/DeleteDirectiveTest.php b/tests/Integration/Schema/Directives/DeleteDirectiveTest.php index 1342524e98..5f9a48ae39 100644 --- a/tests/Integration/Schema/Directives/DeleteDirectiveTest.php +++ b/tests/Integration/Schema/Directives/DeleteDirectiveTest.php @@ -3,6 +3,7 @@ namespace Tests\Integration\Schema\Directives; use Nuwave\Lighthouse\Exceptions\DefinitionException; +use Nuwave\Lighthouse\Schema\Directives\DeleteDirective; use Tests\DBTestCase; use Tests\Utils\Models\Post; use Tests\Utils\Models\Task; @@ -14,7 +15,7 @@ public function testDeletesUserAndReturnsIt(): void { factory(User::class)->create(); - $this->schema .= ' + $this->schema .= /** @lang GraphQL */ ' type User { id: ID! } @@ -24,7 +25,7 @@ public function testDeletesUserAndReturnsIt(): void } '; - $this->graphQL(' + $this->graphQL(/** @lang GraphQL */ ' mutation { deleteUser(id: 1) { id @@ -45,7 +46,7 @@ public function testDeletesMultipleUsersAndReturnsThem(): void { factory(User::class, 2)->create(); - $this->schema .= ' + $this->schema .= /** @lang GraphQL */ ' type User { id: ID! name: String @@ -56,7 +57,7 @@ public function testDeletesMultipleUsersAndReturnsThem(): void } '; - $this->graphQL(' + $this->graphQL(/** @lang GraphQL */ ' mutation { deleteUsers(id: [1, 2]) { name @@ -290,4 +291,37 @@ public function testDeleteBelongsToThroughNestedArgResolver(): void $task->refresh()->user_id ); } + + public function testNotDeleting(): void + { + User::deleting(function (): bool { + return false; + }); + + $user = factory(User::class)->create(); + + $this->schema .= /** @lang GraphQL */ ' + type User { + id: ID! + } + + type Mutation { + deleteUser(id: ID!): User @delete + } + '; + + $this->graphQL(/** @lang GraphQL */ ' + mutation { + deleteUser(id: 1) { + id + } + } + ')->assertJson([ + 'errors' => [ + [ + 'message' => DeleteDirective::couldNotDelete($user), + ], + ], + ]); + } } From 127be4cf2345c50073e6c38aabb3c6fe2d2f4050 Mon Sep 17 00:00:00 2001 From: Benedikt Franke Date: Sun, 15 Mar 2020 18:40:04 +0000 Subject: [PATCH 02/13] Apply fixes from StyleCI --- src/Schema/Directives/DeleteDirective.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Schema/Directives/DeleteDirective.php b/src/Schema/Directives/DeleteDirective.php index 0c63905b7a..cd5fc194da 100644 --- a/src/Schema/Directives/DeleteDirective.php +++ b/src/Schema/Directives/DeleteDirective.php @@ -2,7 +2,6 @@ namespace Nuwave\Lighthouse\Schema\Directives; -use GraphQL\Error\Error; use GraphQL\Language\AST\FieldDefinitionNode; use GraphQL\Language\AST\InputValueDefinitionNode; use GraphQL\Language\AST\ObjectTypeDefinitionNode; @@ -51,7 +50,7 @@ public static function definition(): string public static function couldNotDelete(Model $user): string { - return 'Could not delete model ' . get_class($user) . ' with ID ' . $user->getKey() . '.'; + return 'Could not delete model '.get_class($user).' with ID '.$user->getKey().'.'; } /** From 02de146b16a2b50917018b13f516acb1b2ac4fe8 Mon Sep 17 00:00:00 2001 From: spawnia Date: Thu, 11 Jun 2020 19:52:54 +0000 Subject: [PATCH 03/13] Prettify docs --- docs/master/eloquent/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/master/eloquent/getting-started.md b/docs/master/eloquent/getting-started.md index 7bddff4f0c..349da4b856 100644 --- a/docs/master/eloquent/getting-started.md +++ b/docs/master/eloquent/getting-started.md @@ -152,7 +152,7 @@ or [@first](../api-reference/directives.md#first), allow you to re-use those sco ```graphql type Query { - users: [User]! @all(scopes: ["verified"]) + users: [User]! @all(scopes: ["verified"]) } ``` From 50b53e858ceda55bb2c34b712ec1106fb8475bd7 Mon Sep 17 00:00:00 2001 From: spawnia Date: Sat, 13 Jun 2020 17:46:44 +0200 Subject: [PATCH 04/13] Clean up DeleteDirective.php --- src/Schema/Directives/DeleteDirective.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Schema/Directives/DeleteDirective.php b/src/Schema/Directives/DeleteDirective.php index 99bfc9c458..f021405d66 100644 --- a/src/Schema/Directives/DeleteDirective.php +++ b/src/Schema/Directives/DeleteDirective.php @@ -103,6 +103,8 @@ public function __invoke($parent, $idOrIds): void $relation->dissociate(); $relation->getParent()->save(); } + + $relation->delete(); } } else { /** @var \Illuminate\Database\Eloquent\Model $related */ From c057c45a84c23c0802ded0c57422bf17e2af1062 Mon Sep 17 00:00:00 2001 From: spawnia Date: Mon, 6 Jul 2020 17:41:38 +0200 Subject: [PATCH 05/13] wip --- src/Schema/Directives/DeleteDirective.php | 9 ++---- .../ModifyModelExistenceDirective.php | 29 ++++++++++++++----- src/SoftDeletes/ForceDeleteDirective.php | 4 +-- src/SoftDeletes/RestoreDirective.php | 4 +-- .../Schema/Directives/DeleteDirectiveTest.php | 4 +-- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/Schema/Directives/DeleteDirective.php b/src/Schema/Directives/DeleteDirective.php index dc93e87350..bcf2ad10ac 100644 --- a/src/Schema/Directives/DeleteDirective.php +++ b/src/Schema/Directives/DeleteDirective.php @@ -47,19 +47,14 @@ public static function definition(): string SDL; } - public static function couldNotDelete(Model $user): string - { - return 'Could not delete model '.get_class($user).' with ID '.$user->getKey().'.'; - } - protected function find(string $modelClass, $idOrIds) { return $modelClass::find($idOrIds); } - protected function modifyExistence(Model $model): void + protected function modifyExistence(Model $model): bool { - $model->delete(); + return (bool) $model->delete(); } /** diff --git a/src/Schema/Directives/ModifyModelExistenceDirective.php b/src/Schema/Directives/ModifyModelExistenceDirective.php index 738018e8f2..083473aa93 100644 --- a/src/Schema/Directives/ModifyModelExistenceDirective.php +++ b/src/Schema/Directives/ModifyModelExistenceDirective.php @@ -2,6 +2,7 @@ namespace Nuwave\Lighthouse\Schema\Directives; +use GraphQL\Error\Error; use GraphQL\Language\AST\FieldDefinitionNode; use GraphQL\Language\AST\ListTypeNode; use GraphQL\Language\AST\NonNullTypeNode; @@ -19,8 +20,6 @@ abstract class ModifyModelExistenceDirective extends BaseDirective implements FieldResolver, FieldManipulator, DefinedDirective { /** - * The GlobalId resolver. - * * @var \Nuwave\Lighthouse\Support\Contracts\GlobalId */ protected $globalId; @@ -30,9 +29,11 @@ public function __construct(GlobalId $globalId) $this->globalId = $globalId; } - /** - * Resolve the field directive. - */ + public static function couldNotModify(Model $user): string + { + return 'Could not modify model '.get_class($user).' with ID '.$user->getKey().'.'; + } + public function resolveField(FieldValue $fieldValue): FieldValue { return $fieldValue->setResolver( @@ -54,14 +55,24 @@ function ($root, array $args) { return; } + $errors = []; + if ($modelOrModels instanceof Model) { - $this->modifyExistence($modelOrModels); + if (! $this->modifyExistence($modelOrModels)) { + $errors []= self::couldNotModify($modelOrModels); + } } elseif ($modelOrModels instanceof Collection) { foreach ($modelOrModels as $model) { - $this->modifyExistence($model); + if(! $this->modifyExistence($model)) { + $errors []= self::couldNotModify($model); + } } } + foreach ($errors as $error) { + // TODO we need a way to report errors without aborting this function + } + return $modelOrModels; } ); @@ -137,6 +148,8 @@ abstract protected function find(string $modelClass, $idOrIds); /** * Bring a model in or out of existence. + * + * The return value indicates if the operation was successful. */ - abstract protected function modifyExistence(Model $model): void; + abstract protected function modifyExistence(Model $model): bool; } diff --git a/src/SoftDeletes/ForceDeleteDirective.php b/src/SoftDeletes/ForceDeleteDirective.php index 5ea7797f5b..f365480c5f 100644 --- a/src/SoftDeletes/ForceDeleteDirective.php +++ b/src/SoftDeletes/ForceDeleteDirective.php @@ -41,10 +41,10 @@ protected function find(string $modelClass, $idOrIds) return $modelClass::withTrashed()->find($idOrIds); } - protected function modifyExistence(Model $model): void + protected function modifyExistence(Model $model): bool { /** @var \Illuminate\Database\Eloquent\Model&\Illuminate\Database\Eloquent\SoftDeletes $model */ - $model->forceDelete(); + return (bool) $model->forceDelete(); } /** diff --git a/src/SoftDeletes/RestoreDirective.php b/src/SoftDeletes/RestoreDirective.php index 6bc4a2155e..3739f1eee9 100644 --- a/src/SoftDeletes/RestoreDirective.php +++ b/src/SoftDeletes/RestoreDirective.php @@ -43,10 +43,10 @@ protected function find(string $modelClass, $idOrIds) return $modelClass::withTrashed()->find($idOrIds); } - protected function modifyExistence(Model $model): void + protected function modifyExistence(Model $model): bool { /** @var \Illuminate\Database\Eloquent\Model&\Illuminate\Database\Eloquent\SoftDeletes $model */ - $model->restore(); + return (bool) $model->restore(); } /** diff --git a/tests/Integration/Schema/Directives/DeleteDirectiveTest.php b/tests/Integration/Schema/Directives/DeleteDirectiveTest.php index 5f9a48ae39..40c6850723 100644 --- a/tests/Integration/Schema/Directives/DeleteDirectiveTest.php +++ b/tests/Integration/Schema/Directives/DeleteDirectiveTest.php @@ -3,7 +3,7 @@ namespace Tests\Integration\Schema\Directives; use Nuwave\Lighthouse\Exceptions\DefinitionException; -use Nuwave\Lighthouse\Schema\Directives\DeleteDirective; +use Nuwave\Lighthouse\Schema\Directives\ModifyModelExistenceDirective; use Tests\DBTestCase; use Tests\Utils\Models\Post; use Tests\Utils\Models\Task; @@ -319,7 +319,7 @@ public function testNotDeleting(): void ')->assertJson([ 'errors' => [ [ - 'message' => DeleteDirective::couldNotDelete($user), + 'message' => ModifyModelExistenceDirective::couldNotModify($user), ], ], ]); From 1ee38bd9b2b3bd3d59c06385fac91730b5588572 Mon Sep 17 00:00:00 2001 From: Benedikt Franke Date: Mon, 6 Jul 2020 15:42:11 +0000 Subject: [PATCH 06/13] Apply fixes from StyleCI --- src/Schema/Directives/ModifyModelExistenceDirective.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Schema/Directives/ModifyModelExistenceDirective.php b/src/Schema/Directives/ModifyModelExistenceDirective.php index 083473aa93..7f651bc5c7 100644 --- a/src/Schema/Directives/ModifyModelExistenceDirective.php +++ b/src/Schema/Directives/ModifyModelExistenceDirective.php @@ -2,7 +2,6 @@ namespace Nuwave\Lighthouse\Schema\Directives; -use GraphQL\Error\Error; use GraphQL\Language\AST\FieldDefinitionNode; use GraphQL\Language\AST\ListTypeNode; use GraphQL\Language\AST\NonNullTypeNode; @@ -59,12 +58,12 @@ function ($root, array $args) { if ($modelOrModels instanceof Model) { if (! $this->modifyExistence($modelOrModels)) { - $errors []= self::couldNotModify($modelOrModels); + $errors [] = self::couldNotModify($modelOrModels); } } elseif ($modelOrModels instanceof Collection) { foreach ($modelOrModels as $model) { - if(! $this->modifyExistence($model)) { - $errors []= self::couldNotModify($model); + if (! $this->modifyExistence($model)) { + $errors [] = self::couldNotModify($model); } } } From c10c922bb7ef30aab2dad6eeaf33d4515230db21 Mon Sep 17 00:00:00 2001 From: spawnia Date: Mon, 6 Jul 2020 19:16:47 +0200 Subject: [PATCH 07/13] Add ErrorPool to allow for partial errors --- src/Execution/ErrorPool.php | 53 +++++++++++++++++++ src/GraphQL.php | 27 +++++----- src/LighthouseServiceProvider.php | 2 + .../ModifyModelExistenceDirective.php | 32 ++++++----- 4 files changed, 89 insertions(+), 25 deletions(-) create mode 100644 src/Execution/ErrorPool.php diff --git a/src/Execution/ErrorPool.php b/src/Execution/ErrorPool.php new file mode 100644 index 0000000000..7c72db6cd2 --- /dev/null +++ b/src/Execution/ErrorPool.php @@ -0,0 +1,53 @@ + + */ + protected $throwables = []; + + /** + * Stores an error that will be added to the result. + */ + public function record(Throwable $throwable): void + { + $this->throwables []= $throwable; + } + + /** + * @return array<\GraphQL\Error\Error> + */ + public function errors(): array + { + return array_map( + function (Throwable $throwable): Error { + if ($throwable instanceof Error) { + return $throwable; + } + + return new Error( + $throwable->getMessage(), + null, + null, + null, + null, + $throwable + ); + }, + $this->throwables + ); + } + + public function clear(): void + { + $this->throwables = []; + } +} diff --git a/src/GraphQL.php b/src/GraphQL.php index fe9e58f00f..b90b3352bd 100644 --- a/src/GraphQL.php +++ b/src/GraphQL.php @@ -15,6 +15,7 @@ use Nuwave\Lighthouse\Events\ManipulateResult; use Nuwave\Lighthouse\Events\StartExecution; use Nuwave\Lighthouse\Execution\DataLoader\BatchLoader; +use Nuwave\Lighthouse\Execution\ErrorPool; use Nuwave\Lighthouse\Execution\GraphQLRequest; use Nuwave\Lighthouse\Schema\AST\ASTBuilder; use Nuwave\Lighthouse\Schema\AST\DocumentAST; @@ -26,59 +27,54 @@ class GraphQL { /** - * The executable schema. - * * @var \GraphQL\Type\Schema */ protected $executableSchema; /** - * The schema builder. - * * @var \Nuwave\Lighthouse\Schema\SchemaBuilder */ protected $schemaBuilder; /** - * The pipeline. - * * @var \Nuwave\Lighthouse\Support\Pipeline */ protected $pipeline; /** - * The event dispatcher. - * * @var \Illuminate\Contracts\Events\Dispatcher */ protected $eventDispatcher; /** - * The AST builder. - * * @var \Nuwave\Lighthouse\Schema\AST\ASTBuilder */ protected $astBuilder; /** - * The context factory. - * * @var \Nuwave\Lighthouse\Support\Contracts\CreatesContext */ protected $createsContext; + /** + * @var \Nuwave\Lighthouse\Execution\ErrorPool + */ + protected $errorPool; + public function __construct( SchemaBuilder $schemaBuilder, Pipeline $pipeline, EventDispatcher $eventDispatcher, ASTBuilder $astBuilder, - CreatesContext $createsContext + CreatesContext $createsContext, + ErrorPool $errorPool ) { $this->schemaBuilder = $schemaBuilder; $this->pipeline = $pipeline; $this->eventDispatcher = $eventDispatcher; $this->astBuilder = $astBuilder; $this->createsContext = $createsContext; + $this->errorPool = $errorPool; } /** @@ -167,6 +163,10 @@ public function executeQuery( } } + foreach ($this->errorPool->errors() as $error) { + $result->errors []= $error; + } + $result->setErrorsHandler( function (array $errors, callable $formatter): array { // User defined error handlers, implementing \Nuwave\Lighthouse\Execution\ErrorHandler @@ -231,6 +231,7 @@ protected function getValidationRules(): array protected function cleanUp(): void { BatchLoader::forgetInstances(); + $this->errorPool->clear(); } /** diff --git a/src/LighthouseServiceProvider.php b/src/LighthouseServiceProvider.php index f01be25786..acef9668bd 100644 --- a/src/LighthouseServiceProvider.php +++ b/src/LighthouseServiceProvider.php @@ -27,6 +27,7 @@ use Nuwave\Lighthouse\Console\UnionCommand; use Nuwave\Lighthouse\Console\ValidateSchemaCommand; use Nuwave\Lighthouse\Execution\ContextFactory; +use Nuwave\Lighthouse\Execution\ErrorPool; use Nuwave\Lighthouse\Execution\GraphQLRequest; use Nuwave\Lighthouse\Execution\GraphQLValidator; use Nuwave\Lighthouse\Execution\LighthouseRequest; @@ -109,6 +110,7 @@ public function register(): void $this->app->singleton(DirectiveFactory::class); $this->app->singleton(NodeRegistry::class); $this->app->singleton(TypeRegistry::class); + $this->app->singleton(ErrorPool::class); $this->app->singleton(CreatesContext::class, ContextFactory::class); $this->app->singleton(CanStreamResponse::class, ResponseStream::class); diff --git a/src/Schema/Directives/ModifyModelExistenceDirective.php b/src/Schema/Directives/ModifyModelExistenceDirective.php index 7f651bc5c7..f19740b60e 100644 --- a/src/Schema/Directives/ModifyModelExistenceDirective.php +++ b/src/Schema/Directives/ModifyModelExistenceDirective.php @@ -2,6 +2,7 @@ namespace Nuwave\Lighthouse\Schema\Directives; +use GraphQL\Error\Error; use GraphQL\Language\AST\FieldDefinitionNode; use GraphQL\Language\AST\ListTypeNode; use GraphQL\Language\AST\NonNullTypeNode; @@ -9,6 +10,7 @@ use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Nuwave\Lighthouse\Exceptions\DefinitionException; +use Nuwave\Lighthouse\Execution\ErrorPool; use Nuwave\Lighthouse\Schema\AST\DocumentAST; use Nuwave\Lighthouse\Schema\Values\FieldValue; use Nuwave\Lighthouse\Support\Contracts\DefinedDirective; @@ -23,9 +25,15 @@ abstract class ModifyModelExistenceDirective extends BaseDirective implements Fi */ protected $globalId; - public function __construct(GlobalId $globalId) + /** + * @var \Nuwave\Lighthouse\Execution\ErrorPool + */ + protected $errorPool; + + public function __construct(GlobalId $globalId, ErrorPool $errorPool) { $this->globalId = $globalId; + $this->errorPool = $errorPool; } public static function couldNotModify(Model $user): string @@ -54,24 +62,24 @@ function ($root, array $args) { return; } - $errors = []; + $modifyModelExistence = function (Model $model): void { + if (! $this->modifyExistence($model)) { + $this->errorPool->record( + new Error( + self::couldNotModify($model) + ) + ); + } + }; if ($modelOrModels instanceof Model) { - if (! $this->modifyExistence($modelOrModels)) { - $errors [] = self::couldNotModify($modelOrModels); - } + $modifyModelExistence($modelOrModels); } elseif ($modelOrModels instanceof Collection) { foreach ($modelOrModels as $model) { - if (! $this->modifyExistence($model)) { - $errors [] = self::couldNotModify($model); - } + $modifyModelExistence($model); } } - foreach ($errors as $error) { - // TODO we need a way to report errors without aborting this function - } - return $modelOrModels; } ); From 308be5b9c7965902dbe4adec5ec0a1e5ea493d8d Mon Sep 17 00:00:00 2001 From: Benedikt Franke Date: Mon, 6 Jul 2020 17:17:00 +0000 Subject: [PATCH 08/13] Apply fixes from StyleCI --- src/Execution/ErrorPool.php | 2 +- src/GraphQL.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Execution/ErrorPool.php b/src/Execution/ErrorPool.php index 7c72db6cd2..3dfd8db9f2 100644 --- a/src/Execution/ErrorPool.php +++ b/src/Execution/ErrorPool.php @@ -19,7 +19,7 @@ class ErrorPool */ public function record(Throwable $throwable): void { - $this->throwables []= $throwable; + $this->throwables [] = $throwable; } /** diff --git a/src/GraphQL.php b/src/GraphQL.php index b90b3352bd..450b13d18c 100644 --- a/src/GraphQL.php +++ b/src/GraphQL.php @@ -164,7 +164,7 @@ public function executeQuery( } foreach ($this->errorPool->errors() as $error) { - $result->errors []= $error; + $result->errors [] = $error; } $result->setErrorsHandler( From 1f91079ec69dfcbcbb4cb68720291704a19cafef Mon Sep 17 00:00:00 2001 From: Benedikt Franke Date: Fri, 17 Jul 2020 11:43:08 +0200 Subject: [PATCH 09/13] Document --- CHANGELOG.md | 2 ++ docs/master/digging-deeper/error-handling.md | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1d1d0ba54..4246e79d56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ You can find and compare releases at the [GitHub release page](https://github.co - Publish config file with tag `lighthouse-config` and default schema with tag `lighthouse-schema` instead of the previously used tags `config` and `schema` https://github.com/nuwave/lighthouse/issues/1489 +- Throw partial errors when failing to delete, forceDelete or restore a model https://github.com/nuwave/lighthouse/pull/1420 +- Add `\Nuwave\Lighthouse\Execution\ErrorPool` to allow collection of partial errors https://github.com/nuwave/lighthouse/pull/1420 ### Fixed diff --git a/docs/master/digging-deeper/error-handling.md b/docs/master/digging-deeper/error-handling.md index 87a12cc7ab..9badca78ff 100644 --- a/docs/master/digging-deeper/error-handling.md +++ b/docs/master/digging-deeper/error-handling.md @@ -166,8 +166,21 @@ class ExtensionErrorHandler implements ErrorHandler } ``` -## Collecting Errors +## Partial Errors As a GraphQL query may return a partial result, you may not always want to abort -execution immediately after an error occurred. You can use the [`\Nuwave\Lighthouse\Execution\ErrorBuffer`](https://github.com/nuwave/lighthouse/blob/master/src/Execution/ErrorBuffer.php) +execution immediately after an error occurred. + +Use the [`ErrorPool`](https://github.com/nuwave/lighthouse/blob/master/src/Execution/ErrorPool.php) when you want to collect multiple errors before returning a result. + +```php +try { + // Something that might fail but still allows for a partial result +} catch (\Throwable $error) { + $errorPool = app(\Nuwave\Lighthouse\Execution\ErrorPool::class); + $errorPool->record($error); +} + +return $result; +``` From 354f8f6206c68ab940ceb24aab40ecc6bfad3301 Mon Sep 17 00:00:00 2001 From: Benedikt Franke Date: Fri, 17 Jul 2020 11:46:16 +0200 Subject: [PATCH 10/13] Deprecate `\Nuwave\Lighthouse\Execution\ErrorBuffer` in favor of `\Nuwave\Lighthouse\Execution\ErrorPool` --- CHANGELOG.md | 4 ++++ UPGRADE.md | 16 ++++++++++++++++ src/Execution/ErrorBuffer.php | 4 ++++ 3 files changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4246e79d56..5415c6f71d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,10 @@ You can find and compare releases at the [GitHub release page](https://github.co - Ensure the `@count` directive works properly with polymorphic relations https://github.com/nuwave/lighthouse/pull/1466 +### Deprecated + +- Deprecate `\Nuwave\Lighthouse\Execution\ErrorBuffer` in favor of `\Nuwave\Lighthouse\Execution\ErrorPool` https://github.com/nuwave/lighthouse/pull/1420 + ## 4.15.0 ### Added diff --git a/UPGRADE.md b/UPGRADE.md index 62ed9bc23d..35e690d973 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -195,3 +195,19 @@ If you need to revert to the old behavior of using `fill()`, you can change your - 'force_fill' => true, + 'force_fill' => false, ``` + +### Replace `ErrorBuffer` with `ErrorPool` + +Collecting partial errors is now done through the singleton `\Nuwave\Lighthouse\Execution\ErrorPool` +instead of `\Nuwave\Lighthouse\Execution\ErrorBuffer`: + +```php +try { + // Something that might fail but still allows for a partial result +} catch (\Throwable $error) { + $errorPool = app(\Nuwave\Lighthouse\Execution\ErrorPool::class); + $errorPool->record($error); +} + +return $result; +``` diff --git a/src/Execution/ErrorBuffer.php b/src/Execution/ErrorBuffer.php index 48ec0d096a..32638d6634 100644 --- a/src/Execution/ErrorBuffer.php +++ b/src/Execution/ErrorBuffer.php @@ -5,6 +5,10 @@ use Closure; use Nuwave\Lighthouse\Exceptions\GenericException; +/** + * @deprecated in favor of + * @see \Nuwave\Lighthouse\Execution\ErrorPool + */ class ErrorBuffer { /** From 885f0c31f551b439808054d24e14d81e0f238cc1 Mon Sep 17 00:00:00 2001 From: spawnia Date: Fri, 17 Jul 2020 09:58:28 +0000 Subject: [PATCH 11/13] Prettify docs --- docs/master/security/validation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/master/security/validation.md b/docs/master/security/validation.md index 1e32649ebb..351b5a6d20 100644 --- a/docs/master/security/validation.md +++ b/docs/master/security/validation.md @@ -169,7 +169,7 @@ You can customize the messages for the given rules by implementing the `messages ## Customize Query Validation Rules By default, Lighthouse enables all default query validation rules from `webonyx/graphql-php`. -This covers fundamental checks, e.g. queried fields match the schema, variables have values of the correct type. +This covers fundamental checks, e.g. queried fields match the schema, variables have values of the correct type. If you want to add custom rules or change which ones are used, you can bind a custom implementation of the interface `\Nuwave\Lighthouse\Support\Contracts\ProvidesValidationRules` through a service provider. From 93efd11ba95354e7867b1155374d6d94c5184d8e Mon Sep 17 00:00:00 2001 From: spawnia Date: Fri, 17 Jul 2020 11:39:06 +0000 Subject: [PATCH 12/13] Prettify docs --- docs/master/security/authentication.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/master/security/authentication.md b/docs/master/security/authentication.md index 6c11a54dca..306337dff3 100644 --- a/docs/master/security/authentication.md +++ b/docs/master/security/authentication.md @@ -58,7 +58,7 @@ to `sanctum` and register Sanctum's `EnsureFrontendRequestsAreStateful` as first // ... other middleware \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, - ] + ] ], 'guard' => 'sanctum', ``` @@ -131,12 +131,12 @@ Add the following middleware to `config/lighthouse.php`: \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, - + // Or this one when using Laravel Sanctum: \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class - + // ... other middleware - ] + ] ], ``` @@ -144,11 +144,11 @@ The `login` and `logout` might be defined and implement like this: ```graphql type Mutation { - "Log in to a new session and get the user." - login(email: String!, password: String!): User! + "Log in to a new session and get the user." + login(email: String!, password: String!): User! - "Log out from the current session, showing the user one last time." - logout: User @guard + "Log out from the current session, showing the user one last time." + logout: User @guard } ``` @@ -161,8 +161,8 @@ class Login */ public function __invoke($_, array $args): User { - // Plain Laravel: Auth::guard() - // Laravel Sanctum: Auth::guard(config('sanctum.guard', 'web')) + // Plain Laravel: Auth::guard() + // Laravel Sanctum: Auth::guard(config('sanctum.guard', 'web')) $guard = ?; if( ! $guard->attempt($args)) { @@ -190,8 +190,8 @@ class Logout */ public function __invoke($_, array $args): ?User { - // Plain Laravel: Auth::guard() - // Laravel Sanctum: Auth::guard(config('sanctum.guard', 'web')) + // Plain Laravel: Auth::guard() + // Laravel Sanctum: Auth::guard(config('sanctum.guard', 'web')) $guard = ?; /** @var \App\Models\User|null $user */ From fb528fee68dc0b221783ca8a69ac7ce22b3c1545 Mon Sep 17 00:00:00 2001 From: Benedikt Franke Date: Fri, 17 Jul 2020 14:30:17 +0200 Subject: [PATCH 13/13] Add trailing commas --- docs/master/security/authentication.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/master/security/authentication.md b/docs/master/security/authentication.md index 306337dff3..5f39bf7e35 100644 --- a/docs/master/security/authentication.md +++ b/docs/master/security/authentication.md @@ -58,7 +58,7 @@ to `sanctum` and register Sanctum's `EnsureFrontendRequestsAreStateful` as first // ... other middleware \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, - ] + ], ], 'guard' => 'sanctum', ``` @@ -133,10 +133,10 @@ Add the following middleware to `config/lighthouse.php`: \Illuminate\Session\Middleware\StartSession::class, // Or this one when using Laravel Sanctum: - \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class + \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, // ... other middleware - ] + ], ], ```