Skip to content

Commit

Permalink
Prepare v6.49.0
Browse files Browse the repository at this point in the history
  • Loading branch information
spawnia committed Jan 16, 2025
1 parent cc4b1d1 commit 34857fc
Show file tree
Hide file tree
Showing 32 changed files with 75 additions and 133 deletions.
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
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
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 {}
}
11 changes: 6 additions & 5 deletions tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use GraphQL\Error\Error;
use Nuwave\Lighthouse\Execution\AlwaysReportingErrorHandler;
use PHPUnit\Framework\Attributes\Before;
use Tests\FakeExceptionHandler;
use Tests\TestCase;
use Tests\Utils\Exceptions\ClientAwareException;
Expand All @@ -12,7 +13,7 @@ final class AlwaysReportingErrorHandlerTest extends TestCase
{
private FakeExceptionHandler $handler;

/** @before */
#[Before]

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.1 with Laravel ^9 and highest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.2 with Laravel ^9 and highest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.0 with Laravel ^9 and highest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.2 with Laravel ^9 and lowest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.2 with Laravel ^10 and lowest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.3 with Laravel ^9 and highest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.3 with Laravel ^10 and lowest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.1 with Laravel ^9 and lowest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.1 with Laravel ^10 and lowest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.0 with Laravel ^9 and lowest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.

Check failure on line 16 in tests/Integration/Execution/AlwaysReportingErrorHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan on PHP 8.3 with Laravel ^9 and lowest dependencies

Attribute class PHPUnit\Framework\Attributes\Before does not exist.
public function fakeExceptionHandling(): void
{
$this->afterApplicationCreated(function (): void {
Expand Down Expand Up @@ -48,11 +49,11 @@ public static function nonClientSafeErrors(): iterable
public function testNonClientSafeErrors(\Exception $previousError): void
{
$error = new Error(previous: $previousError);
$next = fn (Error $error): array => \compact('error');
$next = fn (Error $error): array => ['error' => $error];

$result = (new AlwaysReportingErrorHandler($this->handler))($error, $next);

$this->assertSame(\compact('error'), $result);
$this->assertSame(['error' => $error], $result);
$this->handler->assertReported($previousError);
}

Expand All @@ -67,11 +68,11 @@ public static function clientSafeErrors(): iterable
public function testClientSafeErrors(?\Exception $previousError): void
{
$error = new Error(previous: $previousError);
$next = fn (Error $error): array => \compact('error');
$next = fn (Error $error): array => ['error' => $error];

$result = (new AlwaysReportingErrorHandler($this->handler))($error, $next);

$this->assertSame(\compact('error'), $result);
$this->assertSame(['error' => $error], $result);
$this->handler->assertReported(match ($previousError) {
null => $error,
default => $previousError,
Expand Down
Loading

0 comments on commit 34857fc

Please sign in to comment.