diff --git a/src/Infer/Definition/ClassDefinition.php b/src/Infer/Definition/ClassDefinition.php index 9affd5be..a86d2e4f 100644 --- a/src/Infer/Definition/ClassDefinition.php +++ b/src/Infer/Definition/ClassDefinition.php @@ -43,6 +43,11 @@ public function isChildOf(string $className) return $this->isInstanceOf($className) && $this->name !== $className; } + public function hasMethodDefinition(string $name): bool + { + return array_key_exists($name, $this->methods); + } + public function getMethodDefinition(string $name, Scope $scope = new GlobalScope, array $indexBuilders = []) { if (! array_key_exists($name, $this->methods)) { diff --git a/src/Support/OperationExtensions/ErrorResponsesExtension.php b/src/Support/OperationExtensions/ErrorResponsesExtension.php index 4610e29e..de7cf3bf 100644 --- a/src/Support/OperationExtensions/ErrorResponsesExtension.php +++ b/src/Support/OperationExtensions/ErrorResponsesExtension.php @@ -82,22 +82,26 @@ private function attachCustomRequestExceptions(FunctionType $methodType) return; } - $methodType->exceptions = [ - ...$methodType->exceptions, - new ObjectType(ValidationException::class), - ]; + $formRequest = $this->infer->analyzeClass($formRequest->name); - $formRequest = $this->infer->analyzeClass($formRequest->name, ['authorize']); - - $authorizeReturnType = $formRequest->getMethodCallType('authorize'); - if ( - (! $authorizeReturnType instanceof LiteralBooleanType) - || $authorizeReturnType->value !== true - ) { + if ($formRequest->hasMethodDefinition('rules')) { $methodType->exceptions = [ ...$methodType->exceptions, - new ObjectType(AuthorizationException::class), + new ObjectType(ValidationException::class), ]; } + + if ($formRequest->hasMethodDefinition('authorize')) { + $authorizeReturnType = $formRequest->getMethodCallType('authorize'); + if ( + (! $authorizeReturnType instanceof LiteralBooleanType) + || $authorizeReturnType->value !== true + ) { + $methodType->exceptions = [ + ...$methodType->exceptions, + new ObjectType(AuthorizationException::class), + ]; + } + } } } diff --git a/tests/ErrorsResponsesTest.php b/tests/ErrorsResponsesTest.php index ab048f85..7160bc98 100644 --- a/tests/ErrorsResponsesTest.php +++ b/tests/ErrorsResponsesTest.php @@ -37,6 +37,16 @@ assertMatchesSnapshot($openApiDocument); }); +it('doesnt add errors with custom request when errors producing methods are not defined', function () { + $openApiDocument = generateForRoute(function () { + return RouteFacade::get('api/test', [ErrorsResponsesTest_Controller::class, 'doesnt_add_errors_with_custom_request_when_errors_producing_methods_not_defined']); + }); + + expect($openApiDocument['paths']['/test']['get']['responses']) + ->toHaveKeys([200]) + ->toHaveCount(1); +}); + it('adds auth error response', function () { RouteFacade::get('api/test', [ErrorsResponsesTest_Controller::class, 'adds_auth_error_response']); @@ -83,6 +93,10 @@ public function adds_errors_with_custom_request(ErrorsResponsesTest_Controller_C { } + public function doesnt_add_errors_with_custom_request_when_errors_producing_methods_not_defined(ErrorsResponsesTest_Controller_CustomRequestWithoutErrorCreatingMethods $request) + { + } + public function adds_auth_error_response(Illuminate\Http\Request $request) { $this->authorize('read'); @@ -116,3 +130,7 @@ public function rules() return ['foo' => 'required']; } } + +class ErrorsResponsesTest_Controller_CustomRequestWithoutErrorCreatingMethods extends \Illuminate\Foundation\Http\FormRequest +{ +}