phpsymfonysymfony6botman

Is there a way to make Symfony controller return nothing?


I use Symfony 6.1 and PHP 8.1. I'm wondering if there is a way to make a Symfony controller return nothing. The why is I'm using Botman and unfortunalty it send itself a response to the client... So I need to make my controller to return nothing.

/**
 * @param Request $request
 *
 * @return Response
 */
#[Route('/botman', methods: 'POST')]
public function test(Request $request): Response
{
    DriverManager::loadDriver(WebDriver::class);
    $adapter = new FilesystemAdapter();

    $botman = BotManFactory::create([], new SymfonyCache($adapter), $request);

    $botman->hears('hello', static function (BotMan $bot) {
        $bot->reply('Yoooooo'); //<- Send a response to the client
    });

    $botman->fallback(static function (BotMan $bot) {
        $bot->reply('try again'); //<- Send a response to the client
    });

    $botman->listen(); // Launch the maching callback

    return new Response(); //Crash because a response have already been sent
}

This is what I get on my browser inspector.

{
    "status": 200,
    "messages": [
        {
            "type": "text",
            "text": "try again",
            "attachment": null,
            "additionalParameters": []
        }
    ]
}{
    "type": "https:\/\/tools.ietf.org\/html\/rfc2616#section-10",
    "title": "An error occurred",
    "status": 500,
    "detail": "Warning: Cannot modify header information - headers already sent by (output started at C:\\Users\\cimba\\Documents\\botman\\vendor\\symfony\\http-foundation\\Response.php:1265)",
    "class": "ErrorException",
    "trace": [...]
}

The only solution I have is to exit(); or die(); instead of the return but I it's not clean for production... Maybe there is a way to avoid BotMan to send it's response or to tell Symfony that I want my controller to return nothing (because botman does without symfony).


Solution

  • I have not used BotMan myself so this is a bit of a guess. You might try seeing if there a BotMan bundle because I suspect that if such a bundle exists then it would deal with this sort of thing as well as eliminating the need to use the static factory method.

    However returning an empty response (which means no headers or content) might do the trick as well.

    # src/Http/EmptyResponse.php
    namespace App\Http;
    
    use Symfony\Component\HttpFoundation\Response;
    
    class EmptyResponse extends Response
    {
        public function send(): static
        {
            // Skip sending headers and content
            // $this->sendHeaders();
            // $this->sendContent();
    
            // Keep some standard Symfony magic
            if (\function_exists('fastcgi_finish_request')) {
                fastcgi_finish_request();
            } elseif (\function_exists('litespeed_finish_request')) {
                litespeed_finish_request();
            } elseif (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
                static::closeOutputBuffers(0, true);
            }
    
            return $this;
        }
    }
    

    Then just return new EmptyResponse(); in your controller.

    I tested this in a regular controller action and Symfony did not complain. But again I have no BotMan setup to test against. Be curious to see if it works.