Как я должен обрабатывать исключения для запросчика данных API? - PullRequest
0 голосов
/ 22 марта 2019

Как мне обработать это исключение для запросчика данных 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 голосов
/ 22 марта 2019

Ваш код выглядит дублированным для меня.Вместо того, чтобы делать 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;
    }
}
0 голосов
/ 22 марта 2019

Если возвращаемое значение касается вас, то вы можете вернуть null или new Task<string>(() => string.Empty), поскольку они в основном означают, что у вас нет данных для возврата.

Теперь все зависит от того, есть ли у вас проект счеткие требования, при которых у вас всегда должно быть значение по умолчанию для возврата или какой-либо другой источник данных, если это значение недоступно, но если вы просто хотите, чтобы код компилировался, у вас может быть простое return null;.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...