diff --git a/CHANGELOG.md b/CHANGELOG.md index 660b78706..3cad9fe87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ You can find and compare releases at the [GitHub release page](https://github.co ## Unreleased +### Changed + +- Respect settings in `GraphQL\Error\Warning` before calling custom `$warningHandler` + ## v15.8.1 ### Fixed diff --git a/docs/class-reference.md b/docs/class-reference.md index 5f0f11c4c..b90425118 100644 --- a/docs/class-reference.md +++ b/docs/class-reference.md @@ -1771,7 +1771,7 @@ const ALL = 63; * * @api */ -static function setWarningHandler(?callable $warningHandler = null): void +static function setWarningHandler(?callable $warningHandler): void ``` ```php diff --git a/src/Error/Warning.php b/src/Error/Warning.php index ac7a56028..850884dba 100644 --- a/src/Error/Warning.php +++ b/src/Error/Warning.php @@ -40,7 +40,7 @@ final class Warning * * @api */ - public static function setWarningHandler(callable $warningHandler = null): void + public static function setWarningHandler(?callable $warningHandler): void { self::$warningHandler = $warningHandler; } @@ -59,7 +59,7 @@ public static function setWarningHandler(callable $warningHandler = null): void public static function suppress($suppress = true): void { if ($suppress === true) { - self::$enableWarnings = 0; + self::$enableWarnings = self::NONE; } elseif ($suppress === false) { self::$enableWarnings = self::ALL; // @phpstan-ignore-next-line necessary until we can use proper unions @@ -87,7 +87,7 @@ public static function enable($enable = true): void if ($enable === true) { self::$enableWarnings = self::ALL; } elseif ($enable === false) { - self::$enableWarnings = 0; + self::$enableWarnings = self::NONE; // @phpstan-ignore-next-line necessary until we can use proper unions } elseif (\is_int($enable)) { self::$enableWarnings |= $enable; @@ -97,26 +97,31 @@ public static function enable($enable = true): void } } - public static function warnOnce(string $errorMessage, int $warningId, int $messageLevel = null): void + public static function warnOnce(string $errorMessage, int $warningId, int $messageLevel = \E_USER_WARNING): void { - $messageLevel ??= \E_USER_WARNING; - - if (self::$warningHandler !== null) { - (self::$warningHandler)($errorMessage, $warningId, $messageLevel); - } elseif ((self::$enableWarnings & $warningId) > 0 && ! isset(self::$warned[$warningId])) { - self::$warned[$warningId] = true; - \trigger_error($errorMessage, $messageLevel); + if (isset(self::$warned[$warningId])) { + return; } + + self::warn($errorMessage, $warningId, $messageLevel); } - public static function warn(string $errorMessage, int $warningId, int $messageLevel = null): void + public static function warn(string $errorMessage, int $warningId, int $messageLevel = \E_USER_WARNING): void { - $messageLevel ??= \E_USER_WARNING; + if (! self::shouldWarn($warningId)) { + return; + } + self::$warned[$warningId] = true; - if (self::$warningHandler !== null) { + if (isset(self::$warningHandler)) { (self::$warningHandler)($errorMessage, $warningId, $messageLevel); - } elseif ((self::$enableWarnings & $warningId) > 0) { + } else { \trigger_error($errorMessage, $messageLevel); } } + + private static function shouldWarn(int $warningId): bool + { + return (self::$enableWarnings & $warningId) > 0; + } } diff --git a/tests/Executor/ExecutorLazySchemaTest.php b/tests/Executor/ExecutorLazySchemaTest.php index c40339fe6..3a2161fcb 100644 --- a/tests/Executor/ExecutorLazySchemaTest.php +++ b/tests/Executor/ExecutorLazySchemaTest.php @@ -129,16 +129,18 @@ public function testWarnsAboutSlowIsTypeOfForLazySchema(): void $result = Executor::execute($schema, Parser::parse($query)); self::assertEquals($expected, $result); + $warnings = []; + Warning::setWarningHandler(function ($warning) use (&$warnings): void { + $warnings[] = $warning; + }); Warning::enable(Warning::WARNING_FULL_SCHEMA_SCAN); $result = Executor::execute($schema, Parser::parse($query)); self::markTestIncomplete('No longer works with PHPUnit 10, reintroduce with https://github.com/webonyx/graphql-php/pull/1393'); - self::assertCount(1, $result->errors); - $error = $result->errors[0] ?? null; - self::assertInstanceOf(Error::class, $error); - self::assertSame( + self::assertEquals($expected, $result); + + self::assertSame([ 'GraphQL Interface Type `Pet` returned `null` from its `resolveType` function for value: instance of GraphQL\Tests\Executor\TestClasses\Dog. Switching to slow resolution method using `isTypeOf` of all possible implementations. It requires full schema scan and degrades query performance significantly. Make sure your `resolveType` function always returns a valid implementation or throws.', - $error->getMessage() - ); + ], $warnings); } public function testHintsOnConflictingTypeInstancesInDefinitions(): void