How to return a value from a HTTP response callback

I am trying to send a HTTP request in c++ with Unreal Engine 5.2 as part of a function, using HttpModule.h and I have a lambda function to handle the response from the request, which works itself. But from the main function I want to return whether the response was successful (i.e. I was able to get an access code in the response data). Here’s a simplification of my code:

TPromise<bool> Success;
Request->OnProcessRequestComplete().BindLambda(
    [&](
        FHttpRequestPtr Request,
        FHttpResponsePtr Response,
        bool ConnectedSuccessfully) mutable
    {
       Success.SetValue(ConnectedSuccessfully);
    }
);
Request->ProcessRequest();

return Success.GetFuture().Get();

I tried using just a bool and updating it in the lambda function and returning it at the end and you can see I also tried to use a TPromise and update it in the lambda function, but this causes unreal to freeze and do nothing.

How can I return whether the response was successful or not?

Code execution is synchronous, a function’s code executes line by line until it returns to the caller. HTTP requests are asynchronous, they are processed in the background and the callback triggers once response is received, several frames later. If you really wanted to wait in the function you’d have to sleep/freeze the program until the response is received, which is possible, but probably not something you want to do.

If you don’t need to support blueprints, the simplest way is to pass a callback parameter to your function.

void Connect(TFunction<void(bool)> ResultCallback)
{
    Request->OnProcessRequestComplete().BindLambda([ResultCallback](FHttpRequestPtr Request, FHttpResponsePtr Response, bool bSuccess)
    {
        ResultCallback(bSuccess);
    });
    Request->ProcessRequest();
}

// Usage:
Connect([](bool bSuccess)
{
    // Code
});

If you need blueprint support, declare event functions or dispatchers that blueprints can override/subscribe to, and trigger them from the response callback.

In many cases (including BP support), you’ll want to handle response in object scope, rather than a raw lambda or static function. Capturing an object (eg. this) in raw lambda is not a good idea. You’ll get better results by binding to a member function with BindUObject, or a smart lambda with BindWeakLambda.

Also in many cases (again), the response lambda will not be executed in game thread and you need to go back to game thread to do whatever.

UFUNCTION(BlueprintImplementableEvent)
void OnConnectResult(bool bSuccess);

Request->OnProccessRequestComplete().BindWeakLambda(this, [this](...)
{
    // Game thread is required to trigger a BP event
    AsyncTask(ENamedThreads::GameThread, [bSuccess]()
    {
        OnConnectResult(bSuccess);
    });
});