mirror of
https://github.com/retailcrm/graphql-php.git
synced 2025-02-11 10:09:24 +03:00
Improved error reporting for invalid field definitions
This commit is contained in:
parent
927997a705
commit
7f1d74f980
@ -65,11 +65,30 @@ class Config
|
||||
public static function validate(array $config, array $definition)
|
||||
{
|
||||
if (self::$enableValidation) {
|
||||
$name = isset($config['name']) ? $config['name'] : 'UnnamedType';
|
||||
$name = isset($config['name']) ? $config['name'] : '(Unnamed Type)';
|
||||
self::validateMap($name, $config, $definition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $typeName
|
||||
* @param array $config
|
||||
* @param array $definition
|
||||
*/
|
||||
public static function validateField($typeName, array $config, array $definition)
|
||||
{
|
||||
if (self::$enableValidation) {
|
||||
if (!isset($config['name'])) {
|
||||
$pathStr = isset($config['type'])
|
||||
? '(Unknown Field of type: ' . Utils::printSafe($config['type']) . ')'
|
||||
: '(Unknown Field)';
|
||||
} else {
|
||||
$pathStr = '';
|
||||
}
|
||||
self::validateMap($typeName ?: '(Unnamed Type)', $config, $definition, $pathStr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $definition
|
||||
* @param int $flags
|
||||
@ -121,7 +140,10 @@ class Config
|
||||
// Make sure that all required keys are present in map
|
||||
$requiredKeys = array_filter($definitions, function($def) {return (self::getFlags($def) & self::REQUIRED) > 0;});
|
||||
$missingKeys = array_keys(array_diff_key($requiredKeys, $map));
|
||||
Utils::invariant(empty($missingKeys), 'Error in "'.$typeName.'" type definition: Required keys missing: "%s"' . $suffix, implode(', ', $missingKeys));
|
||||
Utils::invariant(
|
||||
empty($missingKeys),
|
||||
"Error in '$typeName' type definition: Required keys missing: '%s' $suffix", implode(', ', $missingKeys)
|
||||
);
|
||||
|
||||
// Make sure that every map value is valid given the definition
|
||||
foreach ($map as $key => $value) {
|
||||
@ -226,28 +248,28 @@ class Config
|
||||
Utils::invariant(
|
||||
is_callable($value) || $value instanceof InputType,
|
||||
$err,
|
||||
'callable or instance of GraphQL\Type\Definition\InputType'
|
||||
'callable or InputType definition'
|
||||
);
|
||||
break;
|
||||
case $def & self::OUTPUT_TYPE:
|
||||
Utils::invariant(
|
||||
is_callable($value) || $value instanceof OutputType,
|
||||
$err,
|
||||
'callable or instance of GraphQL\Type\Definition\OutputType'
|
||||
'callable or OutputType definition'
|
||||
);
|
||||
break;
|
||||
case $def & self::INTERFACE_TYPE:
|
||||
Utils::invariant(
|
||||
is_callable($value) || $value instanceof InterfaceType,
|
||||
$err,
|
||||
'callable or instance of GraphQL\Type\Definition\InterfaceType'
|
||||
'callable or InterfaceType definition'
|
||||
);
|
||||
break;
|
||||
case $def & self::OBJECT_TYPE:
|
||||
Utils::invariant(
|
||||
is_callable($value) || $value instanceof ObjectType,
|
||||
$err,
|
||||
'callable or instance of GraphQL\Type\Definition\ObjectType'
|
||||
'callable or ObjectType definition'
|
||||
);
|
||||
break;
|
||||
default:
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
namespace GraphQL\Type\Definition;
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Utils;
|
||||
|
||||
/**
|
||||
* Class FieldDefinition
|
||||
@ -89,30 +91,39 @@ class FieldDefinition
|
||||
|
||||
/**
|
||||
* @param array|Config $fields
|
||||
* @param string $typeName
|
||||
* @return array
|
||||
*/
|
||||
public static function createMap(array $fields)
|
||||
public static function createMap(array $fields, $typeName = null)
|
||||
{
|
||||
$map = [];
|
||||
foreach ($fields as $name => $field) {
|
||||
if (!is_array($field)) {
|
||||
$field = ['type' => $field];
|
||||
}
|
||||
if (!isset($field['name'])) {
|
||||
if (is_string($name)) {
|
||||
$field = ['name' => $name, 'type' => $field];
|
||||
} else {
|
||||
throw new InvariantViolation(
|
||||
"Unexpected field definition for type $typeName at key $name: " . Utils::printSafe($field)
|
||||
);
|
||||
}
|
||||
} elseif (!isset($field['name']) && is_string($name)) {
|
||||
$field['name'] = $name;
|
||||
}
|
||||
$map[$name] = self::create($field);
|
||||
$map[$name] = self::create($field, $typeName);
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|Config $field
|
||||
* @param string $typeName
|
||||
* @return FieldDefinition
|
||||
*/
|
||||
public static function create($field)
|
||||
public static function create($field, $typeName = null)
|
||||
{
|
||||
Config::validate($field, self::getDefinition());
|
||||
if ($typeName) {
|
||||
Config::validateField($typeName, $field, self::getDefinition());
|
||||
}
|
||||
return new self($field);
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
|
||||
$this->fields = [];
|
||||
$fields = isset($this->config['fields']) ? $this->config['fields'] : [];
|
||||
$fields = is_callable($fields) ? call_user_func($fields) : $fields;
|
||||
$this->fields = FieldDefinition::createMap($fields);
|
||||
$this->fields = FieldDefinition::createMap($fields, $this->name);
|
||||
}
|
||||
return $this->fields;
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ class ObjectType extends Type implements OutputType, CompositeType
|
||||
if (null === $this->fields) {
|
||||
$fields = isset($this->config['fields']) ? $this->config['fields'] : [];
|
||||
$fields = is_callable($fields) ? call_user_func($fields) : $fields;
|
||||
$this->fields = FieldDefinition::createMap($fields);
|
||||
$this->fields = FieldDefinition::createMap($fields, $this->name);
|
||||
}
|
||||
return $this->fields;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user