Skip to content

Commit d9e2755

Browse files
committed
Improve error handling for cycles in default values
1 parent 0cf75aa commit d9e2755

3 files changed

Lines changed: 51 additions & 1 deletion

File tree

src/Typesystem/InputType.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Graphpinator\Typesystem\Contract\NamedTypeVisitor;
1010
use Graphpinator\Typesystem\DirectiveUsage\DirectiveUsage;
1111
use Graphpinator\Typesystem\DirectiveUsage\DirectiveUsageSet;
12+
use Graphpinator\Typesystem\Exception\ArgumentDefaultValueCycleDetected;
1213
use Graphpinator\Typesystem\Location\InputObjectLocation;
1314
use Graphpinator\Typesystem\Spec\OneOfDirective;
1415
use Graphpinator\Typesystem\Utils\THasDirectives;
@@ -20,6 +21,7 @@ abstract class InputType extends NamedType
2021
protected const DATA_CLASS = \stdClass::class;
2122

2223
protected ?ArgumentSet $arguments = null;
24+
private bool $isLoadingArguments = false;
2325

2426
public function __construct()
2527
{
@@ -29,6 +31,11 @@ public function __construct()
2931
final public function getArguments() : ArgumentSet
3032
{
3133
if (!$this->arguments instanceof ArgumentSet) {
34+
if ($this->isLoadingArguments) {
35+
throw new ArgumentDefaultValueCycleDetected($this->getName());
36+
}
37+
38+
$this->isLoadingArguments = true;
3239
$this->arguments = $this->getFieldDefinition();
3340
$this->afterGetFieldDefinition();
3441
}

tests/Unit/Typesystem/EnumTypeTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
use Graphpinator\Common\Path;
88
use Graphpinator\Typesystem\EnumType;
9-
use Graphpinator\Typesystem\Spec\DeprecatedDirective;
109
use Graphpinator\Value\Exception\InvalidValue;
1110
use Graphpinator\Value\Visitor\ConvertRawValueVisitor;
1211
use PHPUnit\Framework\Attributes\DataProvider;

tests/Unit/Typesystem/Visitor/ValidateIntegrityVisitorTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Graphpinator\Typesystem\EnumItem\EnumItem;
1313
use Graphpinator\Typesystem\EnumItem\EnumItemSet;
1414
use Graphpinator\Typesystem\EnumType;
15+
use Graphpinator\Typesystem\Exception\ArgumentDefaultValueCycleDetected;
1516
use Graphpinator\Typesystem\Exception\ArgumentInvalidTypeUsage;
1617
use Graphpinator\Typesystem\Exception\DirectiveIncorrectType;
1718
use Graphpinator\Typesystem\Exception\DuplicateNonRepeatableDirective;
@@ -1405,4 +1406,47 @@ protected function getFieldDefinition() : ArgumentSet
14051406
$this->expectException(NameMustNotStartWithDoubleUnderscore::class);
14061407
$directive->accept(new ValidateIntegrityVisitor());
14071408
}
1409+
1410+
public function testArgumentDefaultValueCycleDetected() : void
1411+
{
1412+
$inputA = new class extends InputType {
1413+
protected const NAME = 'InputA';
1414+
1415+
public InputType|null $inputB = null;
1416+
1417+
#[\Override]
1418+
protected function getFieldDefinition() : ArgumentSet
1419+
{
1420+
return new ArgumentSet([
1421+
Argument::create('field', $this->inputB)
1422+
->setDefaultValue(new \stdClass()),
1423+
]);
1424+
}
1425+
};
1426+
1427+
$inputB = new class ($inputA) extends InputType {
1428+
protected const NAME = 'InputB';
1429+
1430+
public function __construct(
1431+
private InputType $inputA,
1432+
)
1433+
{
1434+
parent::__construct();
1435+
}
1436+
1437+
#[\Override]
1438+
protected function getFieldDefinition() : ArgumentSet
1439+
{
1440+
return new ArgumentSet([
1441+
Argument::create('field', $this->inputA)
1442+
->setDefaultValue(new \stdClass()),
1443+
]);
1444+
}
1445+
};
1446+
1447+
$inputA->inputB = $inputB;
1448+
1449+
$this->expectException(ArgumentDefaultValueCycleDetected::class);
1450+
$inputA->accept(new ValidateIntegrityVisitor());
1451+
}
14081452
}

0 commit comments

Comments
 (0)