Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare v6.49.0 #2655

Merged
merged 3 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ You can find and compare releases at the [GitHub release page](https://github.co

## Unreleased

## v6.49.0

### Added

- Make reporting of client-safe errors configurable https://github.com/nuwave/lighthouse/issues/2647
Expand Down
12 changes: 12 additions & 0 deletions docs/6/digging-deeper/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ Client-safe errors are assumed to be something that:

Thus, they are typically not actionable for server developers.

However, you can choose to report client-safe errors by replacing `Nuwave\Lighthouse\Execution\ReportingErrorHandler`
with `Nuwave\Lighthouse\Execution\AlwaysReportingErrorHandler` in the `lighthouse.php` config:

```diff
'error_handlers' => [
- Nuwave\Lighthouse\Execution\ReportingErrorHandler::class,
+ Nuwave\Lighthouse\Execution\AlwaysReportingErrorHandler::class,
],
```

`Nuwave\Lighthouse\Execution\AlwaysReportingErrorHandler` reports all errors through the default Laravel exception handler, regardless of client-safety.

## Additional Error Information

The interface [`GraphQL\Error\ProvidesExtensions`](https://github.com/webonyx/graphql-php/blob/master/src/Error/ProvidesExtensions.php)
Expand Down
9 changes: 3 additions & 6 deletions docs/master/digging-deeper/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ Client-safe errors are assumed to be something that:

Thus, they are typically not actionable for server developers.

However, as Laravel allows to define a [minimum log level](https://laravel.com/docs/errors#exception-log-levels)
at which each individual log channel is triggered, you can choose to report client-safe errors by replacing
`Nuwave\Lighthouse\Execution\ReportingErrorHandler` with `Nuwave\Lighthouse\Execution\AlwaysReportingErrorHandler`
in the `lighthouse.php` config:
However, you can choose to report client-safe errors by replacing `Nuwave\Lighthouse\Execution\ReportingErrorHandler`
with `Nuwave\Lighthouse\Execution\AlwaysReportingErrorHandler` in the `lighthouse.php` config:

```diff
'error_handlers' => [
Expand All @@ -40,8 +38,7 @@ in the `lighthouse.php` config:
],
```

When using `Nuwave\Lighthouse\Execution\AlwaysReportingErrorHandler`, client-safe exceptions will be passed to the
default Laravel exception handler, allowing you to configure appropriate error reporting outside of Lighthouse.
`Nuwave\Lighthouse\Execution\AlwaysReportingErrorHandler` reports all errors through the default Laravel exception handler, regardless of client-safety.

## Additional Error Information

Expand Down
1 change: 0 additions & 1 deletion rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
PHPUnitSetList::PHPUNIT_80,
PHPUnitSetList::PHPUNIT_90,
PHPUnitSetList::PHPUNIT_CODE_QUALITY,
PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES,
]);
$rectorConfig->rule(Rector\CodingStyle\Rector\Closure\StaticClosureRector::class);
$rectorConfig->skip([
Expand Down
8 changes: 2 additions & 6 deletions src/Bind/BindDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ public function validate(
$parentNodeName = $parentNode->name->value;

if (! class_exists($this->class)) {
throw new DefinitionException(
"@bind argument `class` defined on `{$parentNodeName}.{$nodeName}` must be an existing class, received `{$this->class}`.",
);
throw new DefinitionException("@bind argument `class` defined on `{$parentNodeName}.{$nodeName}` must be an existing class, received `{$this->class}`.");
}

if ($this->isModelBinding()) {
Expand All @@ -42,9 +40,7 @@ public function validate(
}

$modelClass = Model::class;
throw new DefinitionException(
"@bind argument `class` defined on `{$parentNodeName}.{$nodeName}` must extend {$modelClass} or define the method `__invoke`, but `{$this->class}` does neither.",
);
throw new DefinitionException("@bind argument `class` defined on `{$parentNodeName}.{$nodeName}` must extend {$modelClass} or define the method `__invoke`, but `{$this->class}` does neither.");
}

public function isModelBinding(): bool
Expand Down
4 changes: 0 additions & 4 deletions src/Events/StartExecution.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,20 @@ public function __construct(
* The parsed schema.
*/
public Schema $schema,

/**
* The client given parsed query string.
*/
public DocumentNode $query,

/**
* The client given variables, neither validated nor transformed.
*
* @var array<string, mixed>|null
*/
public ?array $variables,

/**
* The client given operation name.
*/
public ?string $operationName,

/**
* The context for the operation.
*/
Expand Down
1 change: 1 addition & 0 deletions src/Execution/AlwaysReportingErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use GraphQL\Error\Error;
use Illuminate\Contracts\Debug\ExceptionHandler;

/** Report all errors through the default Laravel exception handler. */
class AlwaysReportingErrorHandler implements ErrorHandler
{
public function __construct(
Expand Down
20 changes: 2 additions & 18 deletions src/GraphQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -315,31 +315,15 @@ public function loadPersistedQuery(string $sha256hash): DocumentNode
|| ! ($cacheConfig['enable'] ?? false)
) {
// https://github.com/apollographql/apollo-server/blob/37a5c862261806817a1d71852c4e1d9cdb59eab2/packages/apollo-server-errors/src/index.ts#L240-L248
throw new Error(
'PersistedQueryNotSupported',
null,
null,
[],
null,
null,
['code' => 'PERSISTED_QUERY_NOT_SUPPORTED'],
);
throw new Error('PersistedQueryNotSupported', null, null, [], null, null, ['code' => 'PERSISTED_QUERY_NOT_SUPPORTED']);
}

$cacheFactory = Container::getInstance()->make(CacheFactory::class);
$store = $cacheFactory->store($cacheConfig['store']);

return $store->get("lighthouse:query:{$sha256hash}")
// https://github.com/apollographql/apollo-server/blob/37a5c862261806817a1d71852c4e1d9cdb59eab2/packages/apollo-server-errors/src/index.ts#L230-L239
?? throw new Error(
'PersistedQueryNotFound',
null,
null,
[],
null,
null,
['code' => 'PERSISTED_QUERY_NOT_FOUND'],
);
?? throw new Error('PersistedQueryNotFound', null, null, [], null, null, ['code' => 'PERSISTED_QUERY_NOT_FOUND']);
}

/** @return ErrorsHandler */
Expand Down
8 changes: 2 additions & 6 deletions src/Pagination/PaginationArgs.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,15 @@ public static function extractArgs(array $args, ResolveInfo $resolveInfo, Pagina
: Arr::get($args, 'page', 1);

if ($first < 0) {
throw new Error(
self::requestedLessThanZeroItems($first),
);
throw new Error(self::requestedLessThanZeroItems($first));
}

// Make sure the maximum pagination count is not exceeded
if (
$paginateMaxCount !== null
&& $first > $paginateMaxCount
) {
throw new Error(
self::requestedTooManyItems($paginateMaxCount, $first),
);
throw new Error(self::requestedTooManyItems($paginateMaxCount, $first));
}

$optimalPaginationType = self::optimalPaginationType($proposedPaginationType, $resolveInfo);
Expand Down
4 changes: 1 addition & 3 deletions src/Schema/AST/ASTBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,7 @@ protected function extendObjectLikeType(string $typeName, ObjectTypeExtensionNod
$extendedObjectLikeType = Parser::objectTypeDefinition(/** @lang GraphQL */ "type {$typeName}");
$this->documentAST->setTypeDefinition($extendedObjectLikeType);
} else {
throw new DefinitionException(
$this->missingBaseDefinition($typeName, $typeExtension),
);
throw new DefinitionException($this->missingBaseDefinition($typeName, $typeExtension));
}
}

Expand Down
10 changes: 2 additions & 8 deletions src/Schema/AST/ASTHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ public static function mergeUniqueNodeList(NodeList|array $original, NodeList|ar
$oldName = $definition->name->value;
$collisionOccurred = in_array($oldName, $newNames);
if ($collisionOccurred && ! $overwriteDuplicates) {
throw new DefinitionException(
static::duplicateDefinition($oldName),
);
throw new DefinitionException(static::duplicateDefinition($oldName));
}

return $collisionOccurred;
Expand Down Expand Up @@ -342,11 +340,7 @@ public static function extractDirectiveDefinition(string $definitionString): Dir
try {
$document = Parser::parse($definitionString);
} catch (SyntaxError $syntaxError) {
throw new DefinitionException(
"Encountered syntax error while parsing this directive definition:\n\n{$definitionString}",
$syntaxError->getCode(),
$syntaxError,
);
throw new DefinitionException("Encountered syntax error while parsing this directive definition:\n\n{$definitionString}", $syntaxError->getCode(), $syntaxError);
}

/** @var \GraphQL\Language\AST\DirectiveDefinitionNode|null $directive */
Expand Down
10 changes: 5 additions & 5 deletions src/Schema/DirectiveLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ public function namespaces(): array
// Built-in and plugin defined directives come next
$this->eventsDispatcher->dispatch(new RegisterDirectiveNamespaces()),
]))
->flatten()
->filter()
// Ensure built-in directives come last
->sortBy(static fn (string $namespace): int => (int) str_starts_with($namespace, 'Nuwave\\Lighthouse'))
->all();
->flatten()
->filter()
// Ensure built-in directives come last
->sortBy(static fn (string $namespace): int => (int) str_starts_with($namespace, 'Nuwave\\Lighthouse'))
->all();
}

/**
Expand Down
4 changes: 1 addition & 3 deletions src/Schema/Directives/BaseDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,7 @@ protected function getMethodArgumentParts(string $argumentName): array
count($argumentParts) > 2
|| empty($argumentParts[0])
) {
throw new DefinitionException(
"Directive '{$this->name()}' must have an argument '{$argumentName}' in the form 'ClassName@methodName' or 'ClassName'",
);
throw new DefinitionException("Directive '{$this->name()}' must have an argument '{$argumentName}' in the form 'ClassName@methodName' or 'ClassName'");
}

/** @var array{0: string, 1?: string} $argumentParts */
Expand Down
6 changes: 1 addition & 5 deletions src/Schema/Directives/ScopeDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@ public function handleBuilder(QueryBuilder|EloquentBuilder|Relation $builder, $v
try {
return $builder->{$scope}($value);
} catch (\BadMethodCallException $badMethodCallException) {
throw new DefinitionException(
"{$badMethodCallException->getMessage()} in @{$this->name()} directive on {$this->nodeName()} argument.",
$badMethodCallException->getCode(),
$badMethodCallException->getPrevious(),
);
throw new DefinitionException("{$badMethodCallException->getMessage()} in @{$this->name()} directive on {$this->nodeName()} argument.", $badMethodCallException->getCode(), $badMethodCallException->getPrevious());
}
}
}
10 changes: 2 additions & 8 deletions src/Schema/Source/SchemaStitcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ class SchemaStitcher implements SchemaSourceProvider
public function __construct(string $rootSchemaPath)
{
if (! file_exists($rootSchemaPath)) {
throw new FileNotFoundException(
"Failed to find a GraphQL schema file at {$rootSchemaPath}. If you just installed Lighthouse, run php artisan vendor:publish --tag=lighthouse-schema",
);
throw new FileNotFoundException("Failed to find a GraphQL schema file at {$rootSchemaPath}. If you just installed Lighthouse, run php artisan vendor:publish --tag=lighthouse-schema.");
}

$this->rootSchemaPath = $rootSchemaPath;
Expand All @@ -43,11 +41,7 @@ protected static function gatherSchemaImportsRecursively(string $path): string
try {
$realpath = \Safe\realpath($importFilePath);
} catch (FilesystemException $filesystemException) {
throw new FileNotFoundException(
"Did not find GraphQL schema import at {$importFilePath}.",
$filesystemException->getCode(),
$filesystemException,
);
throw new FileNotFoundException("Did not find GraphQL schema import at {$importFilePath}.", $filesystemException->getCode(), $filesystemException);
}

return self::gatherSchemaImportsRecursively($realpath);
Expand Down
1 change: 0 additions & 1 deletion src/Schema/Values/FieldValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ class FieldValue
public function __construct(
/** The parent type of the field. */
protected TypeValue $parent,

/** The underlying AST definition of the field. */
protected FieldDefinitionNode $field,
) {}
Expand Down
4 changes: 1 addition & 3 deletions src/Support/Traits/GeneratesColumnsEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ protected function hasAllowedColumns(): bool
$hasColumnsEnum = ! is_null($this->directiveArgValue('columnsEnum'));

if ($hasColumns && $hasColumnsEnum) {
throw new DefinitionException(
"The @{$this->name()} directive can only have one of the following arguments: `columns`, `columnsEnum`.",
);
throw new DefinitionException("The @{$this->name()} directive can only have one of the following arguments: `columns`, `columnsEnum`.");
}

return $hasColumns || $hasColumnsEnum;
Expand Down
2 changes: 1 addition & 1 deletion src/Testing/MakesGraphQLRequests.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ protected function setUpSubscriptionEnvironment(): void
$config->set('lighthouse.subscriptions.storage_ttl', null);

// binding an instance to the container, so it can be spied on
$app->bind(Broadcaster::class, static fn (ConfigRepository $config): \Nuwave\Lighthouse\Subscriptions\Broadcasters\LogBroadcaster => new LogBroadcaster(
$app->bind(Broadcaster::class, static fn (ConfigRepository $config): LogBroadcaster => new LogBroadcaster(
$config->get('lighthouse.subscriptions.broadcasters.log'),
));

Expand Down
2 changes: 1 addition & 1 deletion src/Testing/MakesGraphQLRequestsLumen.php
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ protected function setUpSubscriptionEnvironment(): void
$config->set('lighthouse.subscriptions.storage_ttl', null);

// binding an instance to the container, so it can be spied on
$app->bind(Broadcaster::class, static fn (ConfigRepository $config): \Nuwave\Lighthouse\Subscriptions\Broadcasters\LogBroadcaster => new LogBroadcaster(
$app->bind(Broadcaster::class, static fn (ConfigRepository $config): LogBroadcaster => new LogBroadcaster(
$config->get('lighthouse.subscriptions.broadcasters.log'),
));

Expand Down
2 changes: 1 addition & 1 deletion src/Testing/TestsSubscriptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ protected function setUpTestsSubscriptions(): void
$config->set('lighthouse.subscriptions.storage_ttl', null);

// binding an instance to the container, so it can be spied on
$app->bind(Broadcaster::class, static fn (ConfigRepository $config): \Nuwave\Lighthouse\Subscriptions\Broadcasters\LogBroadcaster => new LogBroadcaster(
$app->bind(Broadcaster::class, static fn (ConfigRepository $config): LogBroadcaster => new LogBroadcaster(
$config->get('lighthouse.subscriptions.broadcasters.log'),
));

Expand Down
12 changes: 2 additions & 10 deletions src/Tracing/FederatedTracing/Proto/Trace/CachePolicy/Scope.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 2 additions & 10 deletions src/Tracing/FederatedTracing/Proto/Trace/HTTP/Method.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/FakeExceptionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ public function render($request, \Throwable $e): Response
throw $e;
}

public function renderForConsole($output, \Throwable $e) {}
public function renderForConsole($output, \Throwable $e): void {}
}
Loading
Loading