Error handling improvements

This commit is contained in:
Yury 2018-10-24 23:51:27 +03:00 committed by GitHub
parent 4c545e5ec4
commit 36b1124d90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 42 deletions

View File

@ -182,12 +182,16 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
if ($previous instanceof ClientAware) { if ($previous instanceof ClientAware) {
$this->isClientSafe = $previous->isClientSafe(); $this->isClientSafe = $previous->isClientSafe();
$this->category = $previous->getCategory() ?: static::CATEGORY_INTERNAL; $this->category = $previous->getCategory() ?: static::CATEGORY_INTERNAL;
} else if ($previous) {
$this->isClientSafe = false;
$this->category = static::CATEGORY_INTERNAL;
} else { } else {
$this->isClientSafe = true; $this->isClientSafe = true;
$this->category = static::CATEGORY_GRAPHQL; while ($previous) {
if (!preg_match('#/webonyx/graphql-php/#u', $previous->getFile())) {
$this->isClientSafe = false;
break;
}
$previous = $previous->getPrevious();
}
$this->category = $this->isClientSafe ? self::CATEGORY_GRAPHQL : self::CATEGORY_INTERNAL;
} }
} }

View File

@ -20,6 +20,7 @@ use GraphQL\Type\Definition\InputType;
use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\InterfaceType;
use GraphQL\Type\Definition\ListOfType; use GraphQL\Type\Definition\ListOfType;
use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\OutputType;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
use GraphQL\Type\Definition\UnionType; use GraphQL\Type\Definition\UnionType;
use GraphQL\Type\Definition\WrappingType; use GraphQL\Type\Definition\WrappingType;

View File

@ -4,6 +4,7 @@ namespace GraphQL\Validator\Rules;
use GraphQL\Error\Error; use GraphQL\Error\Error;
use GraphQL\Language\AST\BooleanValueNode; use GraphQL\Language\AST\BooleanValueNode;
use GraphQL\Language\AST\EnumValueNode; use GraphQL\Language\AST\EnumValueNode;
use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\FloatValueNode; use GraphQL\Language\AST\FloatValueNode;
use GraphQL\Language\AST\IntValueNode; use GraphQL\Language\AST\IntValueNode;
use GraphQL\Language\AST\ListValueNode; use GraphQL\Language\AST\ListValueNode;
@ -15,6 +16,7 @@ use GraphQL\Language\AST\StringValueNode;
use GraphQL\Language\AST\ValueNode; use GraphQL\Language\AST\ValueNode;
use GraphQL\Language\Printer; use GraphQL\Language\Printer;
use GraphQL\Language\Visitor; use GraphQL\Language\Visitor;
use GraphQL\Type\Definition\FieldArgument;
use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\EnumType;
use GraphQL\Type\Definition\EnumValueDefinition; use GraphQL\Type\Definition\EnumValueDefinition;
use GraphQL\Type\Definition\InputObjectType; use GraphQL\Type\Definition\InputObjectType;
@ -33,8 +35,15 @@ use GraphQL\Validator\ValidationContext;
*/ */
class ValuesOfCorrectType extends AbstractValidationRule class ValuesOfCorrectType extends AbstractValidationRule
{ {
static function badValueMessage($typeName, $valueName, $message = null) private static $fieldName;
static function badValueMessage($typeName, $valueName, $message = null, $context = null)
{ {
if ($context && ($arg = $context->getArgument()) && $arg instanceof FieldArgument) {
$fieldName = self::$fieldName;
$argName = $arg->name;
return "Field \"{$fieldName}\" argument \"{$argName}\" requires type {$typeName}, found {$valueName}" . ($message ? "; ${message}" : '.');
}
return "Expected type {$typeName}, found {$valueName}" . return "Expected type {$typeName}, found {$valueName}" .
($message ? "; ${message}" : '.'); ($message ? "; ${message}" : '.');
} }
@ -56,6 +65,11 @@ class ValuesOfCorrectType extends AbstractValidationRule
public function getVisitor(ValidationContext $context) public function getVisitor(ValidationContext $context)
{ {
return [ return [
NodeKind::FIELD => [
'enter' => function (FieldNode $node) {
self::$fieldName = $node->name->value;
}
],
NodeKind::NULL => function(NullValueNode $node) use ($context) { NodeKind::NULL => function(NullValueNode $node) use ($context) {
$type = $context->getInputType(); $type = $context->getInputType();
if ($type instanceof NonNull) { if ($type instanceof NonNull) {
@ -183,7 +197,8 @@ class ValuesOfCorrectType extends AbstractValidationRule
self::badValueMessage( self::badValueMessage(
(string) $locationType, (string) $locationType,
Printer::doPrint($node), Printer::doPrint($node),
$error->getMessage() $error->getMessage(),
$context
), ),
$node, $node,
null, null,

View File

@ -292,7 +292,7 @@ class EnumTypeTest extends \PHPUnit_Framework_TestCase
$this->expectFailure( $this->expectFailure(
'{ colorEnum(fromInt: GREEN) }', '{ colorEnum(fromInt: GREEN) }',
null, null,
"Expected type Int, found GREEN." "Field \"colorEnum\" argument \"fromInt\" requires type Int, found GREEN."
); );
} }

View File

@ -36,7 +36,7 @@ class ValidationTest extends TestCase
'; ';
$expectedError = [ $expectedError = [
'message' => "Expected type Invalid, found \"bad value\"; Invalid scalar is always invalid: bad value", 'message' => "Field \"invalidArg\" argument \"arg\" requires type Invalid, found \"bad value\"; Invalid scalar is always invalid: bad value",
'locations' => [ ['line' => 3, 'column' => 25] ] 'locations' => [ ['line' => 3, 'column' => 25] ]
]; ];

View File

@ -19,6 +19,11 @@ class ValuesOfCorrectTypeTest extends TestCase
); );
} }
private function badValue2($error, $line, $column)
{
return FormattedError::create($error, [new SourceLocation($line, $column)]);
}
private function requiredField($typeName, $fieldName, $fieldTypeName, $line, $column) { private function requiredField($typeName, $fieldName, $fieldTypeName, $line, $column) {
return FormattedError::create( return FormattedError::create(
ValuesOfCorrectType::requiredFieldMessage( ValuesOfCorrectType::requiredFieldMessage(
@ -231,7 +236,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('String', '1', 4, 39) $this->badValue2("Field \"stringArgField\" argument \"stringArg\" requires type String, found 1.", 4, 39)
]); ]);
} }
@ -247,7 +252,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('String', '1.0', 4, 39) $this->badValue2("Field \"stringArgField\" argument \"stringArg\" requires type String, found 1.0.", 4, 39)
]); ]);
} }
@ -263,7 +268,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('String', 'true', 4, 39) $this->badValue2("Field \"stringArgField\" argument \"stringArg\" requires type String, found true.", 4, 39)
]); ]);
} }
@ -279,7 +284,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('String', 'BAR', 4, 39) $this->badValue2("Field \"stringArgField\" argument \"stringArg\" requires type String, found BAR.", 4, 39)
]); ]);
} }
@ -297,7 +302,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Int', '"3"', 4, 33) $this->badValue2("Field \"intArgField\" argument \"intArg\" requires type Int, found \"3\".", 4, 33)
]); ]);
} }
@ -313,7 +318,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Int', '829384293849283498239482938', 4, 33) $this->badValue2("Field \"intArgField\" argument \"intArg\" requires type Int, found 829384293849283498239482938.", 4, 33)
]); ]);
} }
@ -329,7 +334,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Int', 'FOO', 4, 33) $this->badValue2("Field \"intArgField\" argument \"intArg\" requires type Int, found FOO.", 4, 33)
]); ]);
} }
@ -345,7 +350,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Int', '3.0', 4, 33) $this->badValue2("Field \"intArgField\" argument \"intArg\" requires type Int, found 3.0.", 4, 33)
]); ]);
} }
@ -361,7 +366,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Int', '3.333', 4, 33) $this->badValue2("Field \"intArgField\" argument \"intArg\" requires type Int, found 3.333.", 4, 33)
]); ]);
} }
@ -379,7 +384,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Float', '"3.333"', 4, 37) $this->badValue2("Field \"floatArgField\" argument \"floatArg\" requires type Float, found \"3.333\".", 4, 37)
]); ]);
} }
@ -395,7 +400,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Float', 'true', 4, 37) $this->badValue2("Field \"floatArgField\" argument \"floatArg\" requires type Float, found true.", 4, 37)
]); ]);
} }
@ -411,7 +416,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Float', 'FOO', 4, 37) $this->badValue2("Field \"floatArgField\" argument \"floatArg\" requires type Float, found FOO.", 4, 37)
]); ]);
} }
@ -429,7 +434,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Boolean', '2', 4, 41) $this->badValue2("Field \"booleanArgField\" argument \"booleanArg\" requires type Boolean, found 2.", 4, 41)
]); ]);
} }
@ -445,7 +450,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Boolean', '1.0', 4, 41) $this->badValue2("Field \"booleanArgField\" argument \"booleanArg\" requires type Boolean, found 1.0.", 4, 41)
]); ]);
} }
@ -461,7 +466,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Boolean', '"true"', 4, 41) $this->badValue2("Field \"booleanArgField\" argument \"booleanArg\" requires type Boolean, found \"true\".", 4, 41)
]); ]);
} }
@ -477,7 +482,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Boolean', 'TRUE', 4, 41) $this->badValue2("Field \"booleanArgField\" argument \"booleanArg\" requires type Boolean, found TRUE.", 4, 41)
]); ]);
} }
@ -495,7 +500,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('ID', '1.0', 4, 31) $this->badValue2("Field \"idArgField\" argument \"idArg\" requires type ID, found 1.0.", 4, 31)
]); ]);
} }
@ -511,7 +516,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('ID', 'true', 4, 31) $this->badValue2("Field \"idArgField\" argument \"idArg\" requires type ID, found true.", 4, 31)
]); ]);
} }
@ -527,7 +532,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('ID', 'SOMETHING', 4, 31) $this->badValue2("Field \"idArgField\" argument \"idArg\" requires type ID, found SOMETHING.", 4, 31)
]); ]);
} }
@ -713,7 +718,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('String', '2', 4, 55), $this->badValue2("Field \"stringListArgField\" argument \"stringListArg\" requires type String, found 2.", 4, 55),
]); ]);
} }
@ -729,7 +734,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('[String]', '1', 4, 47), $this->badValue2("Field \"stringListArgField\" argument \"stringListArg\" requires type [String], found 1.", 4, 47),
]); ]);
} }
@ -889,8 +894,8 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Int!', '"two"', 4, 32), $this->badValue2("Field \"multipleReqs\" argument \"req2\" requires type Int!, found \"two\".", 4, 32),
$this->badValue('Int!', '"one"', 4, 45), $this->badValue2("Field \"multipleReqs\" argument \"req1\" requires type Int!, found \"one\".", 4, 45),
]); ]);
} }
@ -906,7 +911,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Int!', '"one"', 4, 32), $this->badValue2("Field \"multipleReqs\" argument \"req1\" requires type Int!, found \"one\".", 4, 32),
]); ]);
} }
@ -1058,7 +1063,7 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('String', '2', 5, 40), $this->badValue2("Field \"complexArgField\" argument \"complexArg\" requires type String, found 2.", 5, 40),
]); ]);
} }
@ -1102,13 +1107,7 @@ class ValuesOfCorrectTypeTest extends TestCase
invalidArg(arg: 123) invalidArg(arg: 123)
} }
', [ ', [
$this->badValue( $this->badValue2("Field \"invalidArg\" argument \"arg\" requires type Invalid, found 123; Invalid scalar is always invalid: 123", 3, 27),
'Invalid',
'123',
3,
27,
'Invalid scalar is always invalid: 123'
),
]); ]);
$this->assertEquals( $this->assertEquals(
@ -1163,8 +1162,8 @@ class ValuesOfCorrectTypeTest extends TestCase
} }
} }
', [ ', [
$this->badValue('Boolean!', '"yes"', 3, 28), $this->badValue2("Field \"dog\" argument \"if\" requires type Boolean!, found \"yes\".", 3, 28),
$this->badValue('Boolean!', 'ENUM', 4, 28), $this->badValue2("Field \"name\" argument \"if\" requires type Boolean!, found ENUM.", 4, 28),
]); ]);
} }