Как обрабатывать исключения из вызовов API в Unity и передавать их в пользовательский интерфейс?

Я пытаюсь понять, что делать с некоторыми ошибками в Unity, когда я вызываю API, и как распространить его на пользовательский интерфейс - где и как обрабатывать вещи. Я создал API-интерфейсы aspnet, но там я обычно использовал промежуточное программное обеспечение для обработки ошибок, чтобы поддерживать чистоту своих контроллеров.

Допустим, у нас есть такой код (я использую язык контроллера/репозитория, потому что это то, что я знаю).

  1. Кнопка пользовательского интерфейса запускает событие, подобное OnLoginButtonPressed.

  2. Класс AuthController реагирует на событие, вызывая метод входа в систему, а затем выполняя некоторую логику, когда приходит ответ, следующим образом:

    public async void Login(LoginModel input)
    {
     var result = await AuthRepo.instance.Login(input);
     app.token = result; 
     EventService.OnSuccessfulLogin();
    }
    
  3. Auth.Repo вызывает API и пытается вернуть класс Token (просто оболочка вокруг строки JWT).

     public async Task<Token> Login(LoginModel input)
     {
       string json = JsonConvert.SerializeObject(input);
       var request = UnityWebRequest.Post(app.baseURL + "authentication/login", json);
       request.SetRequestHeader("Content-Type", "application/json");
       request.SendWebRequest();
       while (!request.isDone)
       {
         await Task.Yield();
       }
    
       if (request.result == UnityWebRequest.Result.Success)
       {
         Token token = JsonConvert.DeserializeObject<Token>(request.downloadHandler.text);
         return token;
       }
       else
       {
         throw 
       }
    }
    

Так что без обработки исключений. Итак, я хочу попытаться сообщить пользователю, есть ли ошибка подключения, или они указали неверные данные и т. д. Я предполагаю, что должен добавить некоторую логику в AuthRepo, например:

    if (request.result == UnityWebRequest.Result.Success)
    {
        Token token = JsonConvert.DeserializeObject<Token>(request.downloadHandler.text);
        return token;
    }
    else if (request.result== UnityWebRequest.Result.ConnectionError)
    {
        throw new ConnectionException(request.error);
    }
    else if (request.result == UnityWebRequest.Result.DataProcessingError)
    {
        throw new BadRequestException(request.error);
    }
    else
    {
        throw new System.Exception(request.error);
    }

Кажется, что это много кода, и он окажется в каждом методе в каждом репо (если я не вытащу его в какой-нибудь вспомогательный метод?).... в любом случае, а затем в контроллере я бы сделал что-то вроде:

        try {
            var result = await AuthRepo.instance.Login(input);
            app.token = result; 
            EventService.OnSuccessfulLogin();
        }
        catch (ConnectionException ex)
        {
           EventService.OnConnectionError(ex.Message);
           //some UI object would listen for this event and show the connection error message.
        }
        catch (BadRequestException ex)
        {
           EventService.LoginFailedError(ex.Message);
        }
        finally
        {
           EventService.UnknownError(ex.Message);
        }

Это совершенно неправильный путь? Похоже, что код просто завалится обработкой исключений, или это правильный путь?

Я просмотрел несколько видеороликов на YouTube, которые, кажется, предполагают, что это правильно, но на самом деле они не показывают мой вариант использования (разговор с API), поэтому я просто пытаюсь быть уверенным.

Я не вижу ничего плохого в том, что в коде много обработки исключений ... Я бы предпочел абстрагировать это в EventService.HandleException и позволить службе решать в центральном месте, какие из них он знает, а какие Неизвестная ошибка => в вашем коде есть всегда будет один catch(Exception e) { EvntService.HandlException(e); } => таким образом, все известные исключения и возможные конкретные отображения находятся в одном центральном месте.. можно добавить дополнительные параметры/перегрузки в HandleException, если это необходимо, например. опуская сообщение об исключении, но передайте собственное сообщение и т. д.

derHugo 10.01.2023 15:11

Кстати .. finally всегда выполняется .. также в случае успеха и ex в этом случае не существовало бы

derHugo 10.01.2023 15:15
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Laravel - это мощный PHP-фреймворк, используемый для создания масштабируемых и надежных веб-приложений. Одним из преимуществ Laravel является его...
Что такое двойные вопросительные знаки (??) в JavaScript?
Что такое двойные вопросительные знаки (??) в JavaScript?
Как безопасно обрабатывать неопределенные и нулевые значения в коде с помощью Nullish Coalescing
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание API-ресурса Laravel может быть непростой задачей. Она требует глубокого понимания возможностей Laravel и лучших практик, чтобы обеспечить...
Как сделать компонент справочного центра с помощью TailwindCSS
Как сделать компонент справочного центра с помощью TailwindCSS
Справочный центр - это веб-сайт, где клиенты могут найти ответы на свои вопросы и решения своих проблем. Созданный для решения многих распространенных...
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
1
2
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку UnityWebRequest.Result — это перечисление, здесь вы можете начать с оператора switch. Это не только чище, но и работает лучше.

Еще одна вещь, которую вы можете сделать, это создать абстрактный класс (например, APIException) и сделать его ответственным за создание правильных экземпляров исключений, предоставив ему какой-нибудь статический метод, такой как APIException FromUWRResult(UnityWebRequest.Result result).

Обработка исключений также может быть выполнена в APIException. Дайте ему абстрактный метод Handle() и реализуйте его соответствующим образом в каждом из производных классов.

Теперь ваш код будет выглядеть так:

var ex = APIException.FromUWRResult(request.result);
if (ex != null) {
    throw ex;
}

...

catch(APIException ex) {
    ex.Handle();
}

Другие вопросы по теме