Documentation index for AI agents

에러 핸들링 구현 패턴

GS2 를 사용한 게임 개발에서의 실전적인 에러 핸들링과 재시도 전략 모범 사례

GS2 를 이용한 네트워크 기능 구현에서 에러 핸들링은 게임의 안정성과 사용자 경험(UX)에 직결됩니다. 여기서는 단순히 예외를 포착하는 데 그치지 않는 실전적인 구현 패턴을 소개합니다.

1. 에러 분류와 대응 방침

GS2 의 예외는 그 성질에 따라 크게 3가지로 분류할 수 있습니다.

분류해당하는 예외 (예)대응 방침
일시적인 에러InternalServerError, ServiceUnavailable, RequestTimeout자동 재시도. 몇 차례 시도해도 안 되는 경우 에러 다이얼로그를 표시.
로직/설정 에러BadRequest, NotFound개발 중에 해결해야 할 에러. 릴리스 후에는 버그로 간주하여 로그를 수집하고, 사용자에게는 적절한 메시지를 표시.
인증·상태 에러Unauthorized, Conflict, QuotaLimitExceeded특별한 복구 처리가 필요. 재로그인이나 데이터 재동기화(도메인 재취득)를 수행.

2. 재시도 전략 구현(지수 백오프)

서버의 과부하나 일시적인 네트워크 불안정으로 인한 에러에 대해서는 즉시 재시도하는 것이 아니라, 간격을 두고 재시도하는 “지수 백오프(Exponential Backoff)“가 권장됩니다.

Unity / C# 에서의 예(자동 재시도)

public async Task<T> ExecuteWithAutoRetry<T>(Func<Task<T>> action, int maxRetries = 3)
{
    for (int i = 0; i < maxRetries; i++)
    {
        try
        {
            return await action();
        }
        catch (Gs2.Core.Exception.Gs2Exception e) when (e.RecommendAutoRetry) // 자동 재시도가 권장되는지 판정
        {
            if (i == maxRetries - 1) throw;

            // 지수 백오프: 1s, 2s, 4s...
            await Task.Delay((int)Math.Pow(2, i) * 1000);
        }
    }
    throw new Exception("Reached unreachable code");
}

수동 재시도 판단

RecommendAutoRetryfalse 이고 RecommendRetrytrue 인 경우(예: ConflictExceptionQuotaLimitExceededException), 자동으로 계속 반복하면 상황을 악화시킬 가능성이 있으므로, 사용자에게 확인을 요청하는 다이얼로그를 표시하여 재시도하게 하는 것이 일반적입니다.

3. 인증 에러(UnauthorizedException)의 자동 복구

액세스 토큰의 유효기간 만료 등으로 UnauthorizedException 이 발생한 경우, 사용자에게 타이틀 화면으로 돌아가도록 안내하는 것이 아니라, 백그라운드에서 자동으로 재로그인하여 요청을 재시도하는 것이 이상적입니다.

구현 예시

try
{
    await gs2.Inventory.Namespace("...").Me(GameSession).Inventory("...").ModelAsync();
}
catch (Gs2.Core.Exception.UnauthorizedException)
{
    // 1. 백그라운드에서 재로그인 처리를 실행
    GameSession = await ReLogin();
    
    // 2. 새로운 GameSession 을 사용하여 요청을 재시도
    await gs2.Inventory.Namespace("...").Me(GameSession).Inventory("...").ModelAsync();
}

4. 충돌(ConflictException) 해소

스탬프 시트 실행 중에 통신이 끊긴 경우 등에 ConflictException 이 발생할 수 있습니다. 이는 “이전 처리가 아직 서버 측에서 완료되지 않았거나, 혹은 중복되고 있다"는 것을 나타냅니다.

  • 대응책: 대부분의 경우 단순한 재시도로 해결됩니다. GS2 SDK 의 상위 레벨 API(Domain 오브젝트)를 사용하는 경우, 내부 캐시와 서버 상태 사이에 불일치가 있을 가능성이 있으므로 Domain 오브젝트를 다시 가져온 후 재시도할 것을 권장합니다.

5. 사용자에게 주는 피드백(UX)

모든 에러에 대해 다이얼로그를 표시하면 사용자는 스트레스를 느낍니다.

  1. 사일런트 재시도: 일시적인 에러는 우선 백그라운드에서 1~2회 재시도합니다. 그동안 UI 에는 “통신 중…” 인디케이터만 표시합니다.
  2. 복구 가능한 다이얼로그: 재시도해도 실패한 경우, “통신에 실패했습니다. 전파가 양호한 곳에서 다시 시도해 주세요"와 같은 메시지와 [재시도] [타이틀로] 버튼을 표시합니다.
  3. 치명적인 에러: 점검 중이거나 앱 버전의 강제 업데이트가 필요한 경우에는, 타이틀 화면으로 돌아가는 것 외에는 선택지가 없는 전용 다이얼로그를 표시합니다.

정리

  • 재시도 가능한 에러에는 지수 백오프를 적용한다.
  • 인증 에러는 자동 재로그인으로 감춘다.
  • 개발 중에는 카오스 모드를 활성화하여 이러한 핸들링이 올바르게 동작하는지 검증한다.