Skip to content

Commit

Permalink
Improved interface contract error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
peldax committed Jan 9, 2021
1 parent 7aa7850 commit 50152f1
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 12 deletions.
9 changes: 8 additions & 1 deletion src/Exception/Type/ArgumentConstraintNotContravariant.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,12 @@

final class ArgumentConstraintNotContravariant extends \Graphpinator\Exception\Type\TypeError
{
public const MESSAGE = 'Argument constraint is not contravariant.';
public const MESSAGE = 'Type "%s" does not satisfy interface "%s" - argument "%s" on field "%s" has constraint which is not contravariant.';

public function __construct(string $childName, string $interfaceName, string $fieldName, string $argumentName)
{
$this->messageArgs = [$childName, $interfaceName, $argumentName, $fieldName];

parent::__construct();
}
}
9 changes: 8 additions & 1 deletion src/Exception/Type/FieldConstraintNotCovariant.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,12 @@

final class FieldConstraintNotCovariant extends \Graphpinator\Exception\Type\TypeError
{
public const MESSAGE = 'Field constraint is not covariant.';
public const MESSAGE = 'Type "%s" does not satisfy interface "%s" - field "%s" has constraint which is not covariant.';

public function __construct(string $childName, string $interfaceName, string $fieldName)
{
$this->messageArgs = [$childName, $interfaceName, $fieldName];

parent::__construct();
}
}
9 changes: 8 additions & 1 deletion src/Exception/Type/InterfaceContractArgumentTypeMismatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,12 @@

final class InterfaceContractArgumentTypeMismatch extends \Graphpinator\Exception\Type\TypeError
{
public const MESSAGE = 'Type doesnt satisfy interface - argument type does not match';
public const MESSAGE = 'Type "%s" does not satisfy interface "%s" - argument "%s" on field "%s" does not have a compatible type.';

public function __construct(string $childName, string $interfaceName, string $fieldName, string $argumentName)
{
$this->messageArgs = [$childName, $interfaceName, $argumentName, $fieldName];

parent::__construct();
}
}
9 changes: 8 additions & 1 deletion src/Exception/Type/InterfaceContractFieldTypeMismatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,12 @@

final class InterfaceContractFieldTypeMismatch extends \Graphpinator\Exception\Type\TypeError
{
public const MESSAGE = 'Type doesnt satisfy interface - field type does not match';
public const MESSAGE = 'Type "%s" does not satisfy interface "%s" - field "%s" does not have a compatible type.';

public function __construct(string $childName, string $interfaceName, string $fieldName)
{
$this->messageArgs = [$childName, $interfaceName, $fieldName];

parent::__construct();
}
}
9 changes: 8 additions & 1 deletion src/Exception/Type/InterfaceContractMissingArgument.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,12 @@

final class InterfaceContractMissingArgument extends \Graphpinator\Exception\Type\TypeError
{
public const MESSAGE = 'Type doesnt satisfy interface - field has missing argument';
public const MESSAGE = 'Type "%s" does not satisfy interface "%s" - argument "%s" on field "%s" is missing.';

public function __construct(string $childName, string $interfaceName, string $fieldName, string $argumentName)
{
$this->messageArgs = [$childName, $interfaceName, $argumentName, $fieldName];

parent::__construct();
}
}
9 changes: 8 additions & 1 deletion src/Exception/Type/InterfaceContractMissingField.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,12 @@

final class InterfaceContractMissingField extends \Graphpinator\Exception\Type\TypeError
{
public const MESSAGE = 'Type doesnt satisfy interface - missing field';
public const MESSAGE = 'Type "%s" does not satisfy interface "%s" - missing field "%s".';

public function __construct(string $childName, string $interfaceName, string $fieldName)
{
$this->messageArgs = [$childName, $interfaceName, $fieldName];

parent::__construct();
}
}
39 changes: 33 additions & 6 deletions src/Type/Contract/TInterfaceImplementor.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,32 +54,59 @@ protected function validateInterfaces() : void

foreach ($interface->getFields() as $fieldContract) {
if (!$this->getFields()->offsetExists($fieldContract->getName())) {
throw new \Graphpinator\Exception\Type\InterfaceContractMissingField();
throw new \Graphpinator\Exception\Type\InterfaceContractMissingField(
$this->getName(),
$interface->getName(),
$fieldContract->getName(),
);
}

$field = $this->getFields()->offsetGet($fieldContract->getName());

if (!$fieldContract->getType()->isInstanceOf($field->getType())) {
throw new \Graphpinator\Exception\Type\InterfaceContractFieldTypeMismatch();
throw new \Graphpinator\Exception\Type\InterfaceContractFieldTypeMismatch(
$this->getName(),
$interface->getName(),
$fieldContract->getName(),
);
}

if (!$fieldContract->getConstraints()->isCovariant($field->getConstraints())) {
throw new \Graphpinator\Exception\Type\FieldConstraintNotCovariant();
throw new \Graphpinator\Exception\Type\FieldConstraintNotCovariant(
$this->getName(),
$interface->getName(),
$fieldContract->getName(),
);
}

foreach ($fieldContract->getArguments() as $argumentContract) {
if (!$field->getArguments()->offsetExists($argumentContract->getName())) {
throw new \Graphpinator\Exception\Type\InterfaceContractMissingArgument();
throw new \Graphpinator\Exception\Type\InterfaceContractMissingArgument(
$this->getName(),
$interface->getName(),
$fieldContract->getName(),
$argumentContract->getName(),
);
}

$argument = $field->getArguments()->offsetGet($argumentContract->getName());

if (!$argument->getType()->isInstanceOf($argumentContract->getType())) {
throw new \Graphpinator\Exception\Type\InterfaceContractArgumentTypeMismatch();
throw new \Graphpinator\Exception\Type\InterfaceContractArgumentTypeMismatch(
$this->getName(),
$interface->getName(),
$fieldContract->getName(),
$argumentContract->getName(),
);
}

if (!$argumentContract->getConstraints()->isContravariant($argument->getConstraints())) {
throw new \Graphpinator\Exception\Type\ArgumentConstraintNotContravariant();
throw new \Graphpinator\Exception\Type\ArgumentConstraintNotContravariant(
$this->getName(),
$interface->getName(),
$fieldContract->getName(),
$argumentContract->getName(),
);
}
}
}
Expand Down

0 comments on commit 50152f1

Please sign in to comment.