我应该如何处理API数据请求者的异常?

时间:2019-03-22 14:01:36

标签: c# async-await

我应该如何处理API数据请求者的此异常? Dostuff1,2,3是3种不同的函数,它们从API检索数据。此功能每分钟运行一次。我想做的是捕获异常,但不停止程序,而是让它在下一次迭代中重试。我该如何解决?我想我不应该使用throw,但是代码要我返回一些东西。

public async Task<string> Dostuff1,2,3()
{
    try
    {
        using (HttpResponseMessage result = await _httpClient.GetAsync(Adrdess))
        using (HttpContent content = result.Content)
        {
            result.EnsureSuccessStatusCode();
            string data = await content.ReadAsStringAsync();
        }

        return data;
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error");
        throw;
    }
}

2 个答案:

答案 0 :(得分:0)

如果返回值是您所关心的,那么您可以返回nullnew Task<string>(() => string.Empty),因为它们基本上意味着您没有要返回的数据。

现在,这取决于您是否有一个明确的要求的项目,如果该项目不可用,则应该始终有一个默认值要返回,或者如果该数据源不可用,则应该有其他一些数据源,但是如果您只想编译代码,则可以有一个简单的return null;

答案 1 :(得分:0)

您的代码对我来说似乎很重复。与其创建3个不同的函数,不如让其带有参数:

public async Task<string> GetStringFromAPIAsync( string resource )
{
        // check input
        if( string.IsNullOrWhitespace(resource) ) throw new ArgumentException(nameof(resource));

        using (HttpResponseMessage result = await _httpClient.GetAsync(resource))
        using (HttpContent content = result.Content)
        {
            result.EnsureSuccessStatusCode();
            return await content.ReadAsStringAsync(); 
            // Issue in your code: 'data' was out of scope for the return.
            // string data = await content.ReadAsStringAsync();
        }
        // return data; <- "data" is not visible here!
}

请记住,我摆脱了这里的所有异常处理,因为从我的POV开始,它应该由调用方完成,这也为您提供了更大的灵活性。

例如:您可以编写另一个重试函数,如下所示:

public async Task<string> GetStringFromAPIWithRetryAsync(string resource, int maxRetry)
{
    // limit retry to 1 .. 100
    for( int retry = Math.Min(Math.Max(1,maxRetry),100); retry > 0 ; retry--){
       try{
          return await GetStringFromAPIAsync( resource );
       }
       catch(Exception ex){ // Actually, you'd only catch exceptions where a retry makes sense.
          if( retry > 0 ){
             Log.Warn("Attempt to get string from {0} failed! Reason: {1}", resource, ex.Message);
          }else{
             throw;
          }
       }
    }
}

如果您只需要默认值以防出错,则可以执行以下操作:

public async Task<string> GetStringFromAPIOrDefaultAsync(string resource, string defaultValue)
{
       string returnValue = defaultValue;
       try{
          returnValue = await GetStringFromAPIAsync( resource );
       }
       catch(Exception){ 
          Log.Warn("Attempt to get string from {0} failed! Reason: {1}", resource, ex.Message);
       }
       return returnValue;
    }
}