Backend.AsyncPoll(); 에서 null exception이 납니다.

문의를 남기실 경우 다음 항목을 작성해 주세요.
정보가 부족한 경우 확인 및 답변이 지연될 수 있습니다.

  • 뒤끝 SDK 버전 : 5.5.1
  • 프로젝트명 : z_survival
  • 스테이터스 코드 :
  • 에러 코드 :
  • 에러 메시지 :

backendhero 샘플에서 보면
using static BackEnd.SendQueue;

if (Backend.IsInitialized == true)
{
//try
//{
Backend.AsyncPoll();
//}
//catch
//{
// Debug.Log(“backend SendQueue null”);
//}
}
으로 비동기 큐 실행 하는 부분이 있는데
여기서 null exception이 납니다.

보니깐

Enqueue(Backend.BMember.LoginWithTheBackendToken, loginBro =>
{
if (loginBro.IsSuccess())
{
Debug.Log("LoginWithTheBackendToken 로그인 성공 ");
SuccessLogin();
}
else
{
// 뒤끝 토큰 로그인 실패
// 개인정보 취급 UI 열기
//DispatcherAction(BackEndUIManager.instance.ShowPrivacyUI);
//정책 팝업열림
Debug.Log("로그인 실패 - " + loginBro.ToString());
}
});
try catch 해보니 여기서 Enqueue가 실행되고 catch로 들어오더라구요 똑같이 서버매니저를 구성했는데 왜 제 프로젝트에선 이런 결과가 나올까요?

안녕하세요 개발자님.

SendQueue의 경우 초기화 함수를 실행해주셔야 합니다.
아래 함수를 참고해주세요.

if(SendQueue.IsInitialize == false)
{
  // SendQueue 초기화
  SendQueue.StartSendQueue(true, ExceptionHandler);
}

void ExceptionHandler(Exception e)
{
  // 예외 처리
}

image

Backend.BMember.CustomLogin(_nickNametext.text, _pWtext.text, callback =>
{
Debug.Log(callback);
에서 로그인 성공 시에 는 문제 없는데
401 exception시 Backend.AsyncPoll(); 에서 위와 같은 문제가 생기네요 알려 주신 대로 SendQueue.StartSendQueue(true, ExceptionHandler); 해도 똑같습니다.

안녕하세요 개발자님.

SendQueue의 경우, Update 함수에서 SendQueue.Poll()을 호출해야합니다.

// example
// 유니티 객체의 Update 함수나 혹은 정기적(1초 이내)로 호출되는 코루틴 등에서 
// Poll 함수를 호출해 주세요.
void Update()
{
    SendQueue.Poll();
}

Backend.AsyncPoll(); 해당 함수의 경우 비동기 함수 관련 Poll()함수이며,
SendQueue와는 무관하다는 점 참고해주시기 바랍니다.

아네 sendqueue 말고 비동기로 했는데
Backend.BMember.CustomLogin(_nickNametext.text, _pWtext.text, callback =>
해당 문제가 발생합니다.

네 그럼 이러한 상황이 맞으실까요?

Backend.BMember.CustomLogin 비동기 호출 시, 응답이 오고(callback) 성공할 경우에는 에러가 발생하지 않고, 401 실패했을 경우에는 다음에 Backend.AsyncPoll에서 에러 발생(Value cannot be null).

먼저 처음 질문해주신 Enqueue(Backend.BMember.LoginWithTheBackendToken, loginBro) 에서 에러가 발생하는 것은 뒤끝SDK 임포트 후 Assets > TheBackend > Toolkit > SendQueueMgr.cs를 오브젝트에 추가하지 않아 발생하는 오류로 추정됩니다. 해당 스크립트는 SendQueue의 초기화 및 Poll 등 SendQueue에 관한것들을 모두 수행하고 있기에 별로의 코드없이 바로 SendQueue.Enqueue를 사용할 수 있습니다.
(없을 경우 수동으로 초기화 및 Poll() 진행)

2번째로 문의해주신 Value cannot be null의 건은 조금 확인을 해야할 것 같습니다.
가능하시다면 아래의 사항들을 공유해주시면 감사하겠습니다.

  1. 뒤끝 초기화 함수 호출 코드
  2. 에러가 발생하기전 마지막으로 호출한 함수 or 호출하자마자 에러가 발생한 함수
  3. Cannot be null이 발생한 로그의 stacktrace
좋아요 1

Backend.BMember.CustomLogin 비동기 호출 시, 응답이 오고(callback) 성공할 경우에는 에러가 발생하지 않고, 401 실패했을 경우에는 다음에 Backend.AsyncPoll에서 에러 발생(Value cannot be null).

  • 이 경우가 맞습니다. 2번 함수 부분 뿐만 아니라 실패 시 해당 부분에서 에러가 발생 하구요.
    해당 문제는 SendQueue를 이용해도 똑같이 일어납니다.
    (SendQueue 시 SendQueueMgr.cs의 Update 함수 안에 BackEnd.SendQueue.Poll(); 에서 남)
  1. 초기화 부분
    // Start is called before the first frame update
    void Start()
    {
    //BackEndUIManager.instance.SetProcessing(true);
    UI.UiManager.Instance.OnNetProgressDimmer(true);
    currentVersion = Application.version;
    var bro = Backend.Initialize(true);
    if (bro.IsSuccess())
    {
    if (bro.IsSuccess() == false)
    {
    Debug.Log("초기화 실패 - " + bro);
    return;
    }
    UI.UiManager.Instance.OnNetProgressDimmer(false);

         // 구글 해시키 획득 
         if (!string.IsNullOrEmpty(Backend.Utils.GetGoogleHash()))
             Debug.Log(Backend.Utils.GetGoogleHash());
         // 서버시간 획득
         Debug.Log(Backend.Utils.GetServerTime());
         // Application 버전 확인
         CheckApplicationVersion();
     }
     else
     {
         UI.UiManager.Instance.Push(UI.EUiPopup.ConfirmPopup, new ConfirmPopup.Param()
         {
             _title = "알림",
             _content = "초기화 실패"
         });
         Debug.Log("초기화 실패 - " + bro);
     }
    

    }

  2. 에러 발생 함수
    Backend.BMember.CustomLogin(_nickNametext.text, _pWtext.text, callback =>
    {
    Debug.Log(callback);

  3. 로그
    statusCode : 401
    errorCode : BadUnauthorizedException
    message : bad customId, 잘못된 customId 입니다

UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:Log(Object)
LoginPage:b__70_0(BackendReturnObject) (at Assets\00_ProjectMulty\02_Script\UI\Page\LoginPage.cs:518)
#C.#B:Invoke()
#C.#E:Poll()
BackEnd.Backend:AsyncPoll()
BackEndServerManager:Update() (at Assets\00_ProjectMulty\02_Script\BackEnd\BackEndServerManager.cs:78)

(Filename: Assets/00_ProjectMulty/02_Script/UI/Page/LoginPage.cs Line: 518)

Uploading Crash Report
ArgumentNullException: Value cannot be null.
Parameter name: key
at #C.#E.Poll () [0x0003e] in :0
at BackEnd.Backend.AsyncPoll () [0x0000f] in :0
at BackEndServerManager.Update () [0x00016] in E:\DoubleStack\InfinityZombie\Client\InfinityDodge\InfinityDodge\Assets\00_ProjectMulty\02_Script\BackEnd\BackEndServerManager.cs:78

(Filename: Line: 0)

  1. 씬에 적용중인 스크립트
    image

넵 정보 제공 감사드립니다.

그러나 해주신 정보를 기반으로 테스트를 진행해보았지만 해당 오류가 발견되지는 않아 해결에 어려움을 겪고 있습니다.

번거로우시겠지만 약간의 테스트만 더 진행해주시면 감사하겠습니다.

  1. 아래의 함수 Debug.Log(callback); 이후에 callback에서 더 진행되는 코드들이 존재하나요?
Backend.BMember.CustomLogin(_nickNametext.text, _pWtext.text, callback =>
{
Debug.Log(callback);

SendQueue와 비동기의 경우, callback에서 발생하는 모든 예외상황은 Poll()에 표시가 됩니다.
만약 아래 추가적으로 코드가 존재하고 해당 코드에서 에러가 발생할 경우에는 Poll()에 에러가 표시될 수 있습니다.

  1. 에러가 발생하는 함수를 동기 형태로 테스트
var callback = Backend.BMember.CustomLogin(_nickNametext.text, _pWtext.text);
Debug.Log(callback);
  1. Backend.BMember.CustomLogin() 이외에 다른 뒤끝 함수를 SendQueue, 비동기 함수로 호출하여 에러가 발생했을 때 Poll에서 에러가 발생하는지 확인.
Backend.GameData.Insert("잘못된 테이블 네임", new Param(), callback =>
{
 Debug.Log(callback);
}

위 3개의 사항들을 한번 체크해주시면 감사하겠습니다.

  1. CustomLogin 함수 부분은 아래와 같습니다.
    {
    Backend.BMember.CustomLogin(_nickNametext.text, _pWtext.text, callback =>
    {
    UI.UiManager.Instance.OnNetProgressDimmer(false);
    Debug.Log(callback);
    if (callback.IsSuccess())
    {
    bro = callback;
    BackEndServerManager._instance.OnBackendAuthorized();
    }
    else
    {
    //string errCode = callback.GetErrorCode();
    string msg = string.Empty;

                switch (int.Parse(callback.GetStatusCode()))
                {
                    case 401:
                        msg = callback.GetMessage().Contains("customId") ? "존재하지 않는 아이디입니다." : "잘못된 비밀번호 입니다.";
                        break;
                    case 409:
                        msg = "중복된 아이디입니다.";
                        break;
                    case 403: // 차단
                        msg = callback.GetErrorCode();
                        break;
                    default:
                        msg = callback.GetMessage();
                        break;
                }
                UiManager.Instance.Push(EUiPopup.ConfirmPopup, new ConfirmPopup.Param()
                {
                    _title = "알림",
                    _content = msg
                });
                //if (msg.Contains("비밀번호"))
                //{
                //    Dispatcher.Instance.Invoke(() => SetPWGuide(msg));
                //}
                //else
                //{
                //    Dispatcher.Instance.Invoke(() => SetIdGuide(msg));
                //}
    
            }
        });
    

}

  1. 동기 형태시 해당 문제가 발생 하지 않습니다.

  2. 문제 발생 하지 않습니다.
    statusCode : 404
    errorCode : NotFoundException
    message : table not found, table을(를) 찾을 수 없습니다

UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:Log(Object)
<>c:b__12_0(BackendReturnObject) (at Assets\00_ProjectMulty\02_Script\UI\Page\LobbyPage.cs:51)
#C.#B:Invoke()
#C.#E:Poll()
BackEnd.Backend:AsyncPoll()
BackEndServerManager:Update() (at Assets\00_ProjectMulty\02_Script\BackEnd\BackEndServerManager.cs:79)

(Filename: Assets/00_ProjectMulty/02_Script/UI/Page/LobbyPage.cs Line: 51)

넵 답변 감사드립니다.

마지막으로 커스텀 로그인의 else 부분 안에 있는 코드를 모두 주석처리한 후 실행해도 에러가 Poll에 에러가 발생하는지 확인해주시면 감사하겠습니다.

Backend.BMember.CustomLogin(_nickNametext.text, _pWtext.text, callback =>
{
    UI.UiManager.Instance.OnNetProgressDimmer(false);
    Debug.Log(callback);
    if (callback.IsSuccess())
    {
        bro = callback;
        BackEndServerManager._instance.OnBackendAuthorized();
    }
   else
   {
      //모두 주석처리
      Debug.LogError(callback);
   }
});

똑같이 발생합니다.

Uploading Crash Report
ArgumentNullException: Value cannot be null.
Parameter name: key
at #C.#E.Poll () [0x0003e] in :0
at BackEnd.Backend.AsyncPoll () [0x0000f] in :0
at BackEndServerManager.Update () [0x00016] in E:\DoubleStack\InfinityZombie\Client\InfinityDodge\InfinityDodge\Assets\00_ProjectMulty\02_Script\BackEnd\BackEndServerManager.cs:79

(Filename: Line: 0)

네 확인 감사합니다.
이번에도 3개의 확인 부탁드리겠습니다

  1. 아래의 코드를 통해 SendQueue로 실행했을 시에도 로그(StackTrace)가 어떻게 발생하는지 알려주실 수 있을까요?
SendQueue(Backend.BMember.CustomLogin, _nickNametext.text, _pWtext.text, callback =>
{
    Debug.Log(callback);
    if (callback.IsSuccess())
    {
       Debug.Log("성공 : " + callback);
    }
   else
   {
      //모두 주석처리
      Debug.LogError("실패 : " + callback);
   }
});
  1. 로그가 발생하는 시간도 유니티 콘솔을 통해 알려주시면 감사하겠습니다.
  • 첫번째 Debug.Log 발생
  • 두번째 Debug.LogError() 발생
  • 세번째 SendQueue.Poll()에서의 에러 발생
  1. 비밀번호가 틀렸을 때 발생하는 에러 또한 Poll()에서 에러가 발생하는지도 확인해주시면 감사하겠습니다.