scramble icon indicating copy to clipboard operation
scramble copied to clipboard

[Bug]: Invalid handling of controller method return type

Open alecpl opened this issue 3 months ago • 3 comments

What happened?

It seems Scramble gets confused by the return type of a controller method. Fot the test case below, it ignores 403/404 cases and for 200 case adds additional "object" response. It works if I remove the return type.

Image

How to reproduce the bug

 /**
     * User information.
     *
     * @param string $id The user identifier
     */
    public function show($id): JsonResponse|UserInfoExtendedResource
    {
        $user = User::find($id);

        if (!$this->checkTenant($user)) {
            return $this->errorResponse(404);
        }

        if (!$this->guard()->user()->canRead($user)) {
            return $this->errorResponse(403);
        }

        return new UserInfoExtendedResource($user);
    }

Package Version

0.12.34

PHP Version

8.2

Laravel Version

11

Which operating systems does with happen with?

Linux

Notes

No response

alecpl avatar Sep 11 '25 10:09 alecpl

Can you share the source of 'errorResponse' @alecpl

romalytvynenko avatar Sep 11 '25 11:09 romalytvynenko

I didn't think it's relevant because Scramble does not have a problem with it. I'm in the middle of Scramble introduction to my code, so I know it's not perfect at this point.

    /**
     * Common error response builder for API (JSON) responses
     *
     * @param int    $code    Error code
     * @param string $message Error message
     * @param array  $data    Additional response data
     */
    public static function errorResponse(int $code, string $message = '', array $data = []): JsonResponse
    {
        $errors = [
            400 => "Bad request",
            401 => "Unauthorized",
            403 => "Access denied",
            404 => "Not found",
            405 => "Method not allowed",
            422 => "Input validation error",
            429 => "Too many requests",
            500 => "Internal server error",
        ];

        $response = [
            'status' => 'error',
            // @var string
            'message' => $message ?: ($errors[$code] ?? "Server error"),
        ];

        if (!empty($data)) {
            $response += $data;
        }

        return response()->json($response, $code);
    }

alecpl avatar Sep 11 '25 12:09 alecpl

i also had a similar problem

code:

    public function upload(UploadChatMessageFileRequest $request): ChatMessageFileResource|JsonResponse
    {
        $file = $request->file('file');
        $storedFile = ChatMessageFileServiceFacade::upload($file);

        return $storedFile !== null
            ? new ChatMessageFileResource($storedFile)
            : response()->json(null, 422);
    }

result: Image

to have only one 200 response instead of 'any of', i've specified #[Response(200, type: 'ChatMessageFileResource')] and it works for 200.

but in 422 error still response only with standard validation error and no empty json (should be both). It could be any other error code and it doesn't combine reponses. Is there any solution for this, to make 'any of' for error responses? Maybe it could be specified like #[Response(422, description: '...', type: 'Illuminate\Validation\ValidationException|object')]? This is just example that doesn't work

arinamirosha avatar Nov 01 '25 14:11 arinamirosha