Eric Brown
Eric Brown

Reputation: 13942

How can I programmatically force an IAsyncOperation into the error state?

I have some C++/WinRT code that asynchronously returns a string. However, some of the internal operations can fail, and when it does, I need to have the IAsyncOperation also move to the error state. co_return obviously moves the operation to the completed state; how can I move the operation to the error state? The stripped down code follows:

winrt::IAsyncOperation<winrt::hstring> MyClass::DoAuthenticationAsync()
{
    auto acctProvider = co_await winrt::WebAuthenticationCoreManager::FindAccountProviderAsync(AccountProviderId, authority, user);
    auto webToken = winrt::WebTokenRequest(acctProvider, CarbonScope, CarbonClientId, winrt::WebTokenRequestPromptType::Default);

    webToken.Properties().Insert(L"authority", authority);
    webToken.Properties().Insert(L"resource", resource);

    auto requestResult = co_await winrt::WebAuthenticationCoreManager::GetTokenSilentlyAsync(webToken);

    auto requestStatus = requestResult.ResponseStatus();
    if (requestStatus == winrt::WebTokenRequestStatus::Success)
    {
        co_return requestResult.ResponseData().GetAt(0).Token();
    }
    else if (requestStatus == winrt::WebTokenRequestStatus::UserInteractionRequired)
    {
        auto uxresult = co_await winrt::WebAuthenticationCoreManager::RequestTokenAsync(webToken);

        requestStatus = uxresult.ResponseStatus();
        if (requestStatus == winrt::WebTokenRequestStatus::Success)
        {
            co_return uxresult.ResponseData().GetAt(0).Token();
        }
    }
    if (requestStatus == winrt::WebTokenRequestStatus::ProviderError)
    {
        // here I'd like to have the IAsyncOperation have an Error status with the ErrorCode from the requestResult.
        auto err = requestResult.ResponseError().ErrorCode();
    }
    co_return L"";
}

Upvotes: 1

Views: 417

Answers (1)

Kenny Kerr
Kenny Kerr

Reputation: 3115

You must throw a winrt::xxx or std::xxx exception. This will be caught at the coroutine boundary and returned across the ABI to the calling language projection, which will typically rethrow the exception. This is specifically designed to work cross-language.

Upvotes: 1

Related Questions