c# - 在服务器关闭时忽略客户端上的异常

时间:2017-12-06 03:12:14

标签: c# android xamarin.android

我使用RestSharp在客户端(Xamarin android app)和我的服务器之间传递数据。
当出现错误时(通常是因为服务器已关闭),执行请求的方法会抛出异常 我希望异常一直返回到调用它的方法,因此我可以向用户抛出错误。

例如,我想登录,但可以说服务器已关闭。

A - 执行请求的方法

public Task<T> ExecuteAsync<T>(RestRequest request) where T : new()
{
    var client = new RestClient
    {
        BaseUrl = new Uri(BaseUrl),
        Authenticator = new HttpBasicAuthenticator(_accountName, _password)
    };

    var taskCompletionSource = new TaskCompletionSource<T>();
    client.ExecuteAsync<T>(request, restResponse =>
    {
        if (restResponse.ErrorException != null)
        {
            throw (new Exception("Server returned an error"));
        }
        taskCompletionSource.SetResult(restResponse.Data);
    });
    return taskCompletionSource.Task;
}

B - 使用方法A执行请求的方法

public static async Task<LoginObject> Login(string accessNumber, string password, string token)
{
    var request = new RestRequest
    {
        Method = Method.POST,
        Resource = "Login"
    };
    request.AddJsonBody(
        new
        {
            accessNumber = accessNumber,
            password = password,
            token = token
        });

    var isDone = await Api.ExecuteAsync<LoginObject>(request);
    return isDone;
}

C - 我想要处理异常的方法

public async Task Login(string PhoneNumber, string Password)
{
    try
    {
        LoginObject login = await LoginServices.Login(PhoneNumber, Password, Token);
        if (login.IsOk)
        {
            // Move to next activity
        }
        else
        {
        Toast.MakeText(this, "Login Error", ToastLength.Short).Show();
        }
    }
    catch (Exception ex) // Here I want to throw the server error
    {
        Toast.MakeText(this, "Server Error", ToastLength.Short).Show();
        return null;
    }
}

现在,当我运行代码时,错误将被抛入A中,并且应用程序崩溃,
我希望它从A到B,从B到C,然后我会向用户显示错误。

编辑:我尝试放置一个try / catch块,但它仍然在A中抛出异常。

2 个答案:

答案 0 :(得分:1)

更改方法A以使签名中包含async,然后将您的最后一行更改为return await taskCompletionSource.Task;

答案 1 :(得分:0)

在您的A方法中,请使用taskCompletionSource.SetException,如下所示:

if (restResponse.ErrorException != null)
 {
   //throw new Exception("Server returned an error");
    taskCompletionSource.SetException(new Exception("Server returned an error"));
 }
 else
 {
    taskCompletionSource.SetResult(restResponse.Data);
 }

在你的B方法中替换这一行:

var isDone = await Api.ExecuteAsync<LoginObject>(request);

用这个来重新抛出异常C-method:

LoginObject isDone=null;
try
{
  isDone = await Api.ExecuteAsync<LoginObject>(request);
}
catch (Exception e)
{
   throw e;
}

This article is talking about TaskCompletionSource