unity3d 如何处理Unity中API调用的异常并将其传递到UI?

lvmkulzt  于 2023-01-17  发布在  其他
关注(0)|答案(1)|浏览(198)

当我调用一个API时,我试图弄清楚如何处理Unity中的一些错误,以及如何将其传播到用户界面-在哪里以及如何处理事情。我已经构建了aspnet API,但在那里我通常会使用一些错误处理中间件来保持我的控制器干净。
假设我们有这样的代码(我使用控制器/存储库语言,因为我知道这些)。

  1. UI按钮触发类似OnLoginButtonPressed的事件。
  2. AuthController类通过调用其login方法来响应事件,然后在响应通过时执行某些逻辑,如下所示:
public async void Login(LoginModel input)
{
 var result = await AuthRepo.instance.Login(input);
 app.token = result; 
 EventService.OnSuccessfulLogin();
}
  1. Auth.Repo调用API并尝试返回一个Token类(只是JWT字符串的 Package 器)
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);
    }

这看起来像是很多代码,并且会在每个repo的每个方法中结束(除非我把它拉到某个helper方法中?)......无论如何,然后在控制器中我会做如下操作:

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对话),所以我只是想确定一下。

gopyfrb3

gopyfrb31#

因为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();
}

相关问题