Skip to main content

How to Handle Accepting Agreements During Connection Errors

Last updated on February 27, 2025

During a network disruption, such as scheduled maintenance or unexpected connection issues, the player's accepted agreements might not be properly updated in the legal service. If this issue is not handled correctly, the player may be left unaware that their agreement status has not been updated, leading to confusion or potential access issues.

To prevent this, it's important to implement error handling that retries the request until it successfully updates the player's agreement status. A common approach is to use a timer-based retry system at the game level. Here's an example of how to implement this retry system with a maximum of 5 retry attempts and retry delay 10 seconds.

...
int MaxRetryAttempts{5};
int NRetryAttempt{0};
int RetryDelay{10};
FTimerHandle RetryTimerHandle;
FDelegateHandle AccelByteAcceptAgreementPoliciesHandle;
int32 LocalUserNum = 0;
...

void AcceptLegal()
{
...
auto ABSubsystem = IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM);
auto AgreementInterface = ABSubsystem->GetAgreementInterface();
auto ABAgreementInterface = StaticCastSharedPtr<FOnlineAgreementAccelBytePtr>(AgreementInterface);
TArray<FABAcceptAgreementPoliciesRequest> DocumentToAccept;
FABAcceptAgreementPoliciesRequest PoliciesRequest;
PoliciesRequest.BasePolicyId = TEXT("<PolicyVersionId>");
PoliciesRequest.LocaleCode = TEXT("en");
DocumentToAccept.Add(PoliciesRequest);

AccelByteAcceptAgreementPoliciesHandle = AgreementInterface->AddAccelByteOnAcceptAgreementPoliciesCompletedDelegate_Handle(LocalUserNum
, FAccelByteOnAcceptAgreementPoliciesCompletedDelegate::CreateLambda([this](int32 AcceptAgreementLocalUserNum, bool bWasSuccessful, const FOnlineErrorAccelByte& ResultState)
{
if (bWasSuccessful)
{
// Do something when the accept the agreement is successful.

NRetryAttempt = 0;
}
else
{
// Implement a solution to handle failed request.
if(NRetryAttempt < MaxRetryAttempts)
{
GetWorld()->GetTimerManager().SetTimer(RetryTimerHandle, [this]()
{
UpdatePlayerMMR();
}, RetryDelay, false);
NRetryAttempt++;
}
else
{
// Show an error message pop up!
}
}

AgreementInterface->ClearAccelByteOnAcceptAgreementPoliciesCompletedDelegate_Handle(LocalUserNum, AccelByteAcceptAgreementPoliciesHandle);
})
);
AgreementInterface->AcceptAgreementPolicies(LocalUserNum, DocumentToAccept);
...
}

If the request encounters one of the error codes listed here, the error delegate will not be triggered when the system starts to retry the request. The error delegate will only be triggered after the retry process ends—either when the retry limit is reached (timeout) or if the final response code is not one of the listed error codes.