Как отловить ошибку API в HttpClient?
Как отловить ошибку API в HttpClient? Ошибки 400..., 500....
Отправляю запросы к API.
Если проблемы на сервере в if(!response.IsSuccessStatusCode)
значение IsSuccessStatusCode
равно ок
(200).
Т.е. через это выражение я не могу получить что у сервера проблемы.
А по факту я получаю JSON с ошибкой
{
"ok": false,
"error": {
"error_code": 406,
"message": "Please enter [data]."
}
}
Если сервер работает без ошибок и я получаю данные с сервера то получаю json типа:
{
"ok": true,
"uuid": "4564-dc12-4d8c-a919-e46541a",
"balance": {
"cost": 7,
"final": 1397
},
"status": "SUCCEEDED",
"execution_time": 1.68081,
"data": {
"total": 4,
"result": [
дальше идут данные
Или после каждого запроса нужно делать DeserializeObject
и проверять соответсвует ли он JSON ошибки?
Фрагмент кода
private async Task Execute(List<string> listID)
{
try
{
foreach (var idParam in list)
{
string url = $"{apiUrl}?id={idParam}";
string resultContent = await _apiClientService.GetContent(url, apiKey);
var user = JsonConvert.DeserializeObject<User>(resultContent);
string line = $"{idParam} | {user.Name} | {user.DateBrth}";
File.WriteAllText("example.txt", line);
}
}
catch (Exception ex)
{
string ms = ex.Message;
_log.LogWithDetailedInfo(ms);
_messageService.ShowOk("Процесс `ID`. Ошибка", ms);
throw;
}
}
public async Task<string> GetContent(string url, string apiKey)
{
string urlResult = url.Replace("\r\n", "").Replace("\n", "");
string content = "";
try
{
var _httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Add("Apikey", apiKey);
var response = await _httpClient.GetAsync(urlResult);
if (!response.IsSuccessStatusCode)
{
_log.LogWithDetailedInfo($"API error: {(int)response.StatusCode} - {response.ReasonPhrase}");
return null;
}
content = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
string msg = ex.Message;
_messageService.ShowOk("ApiClient.Service", msg);
}
return content;
}
Ответы (1 шт):
Автор решения: aepot
→ Ссылка
Берём вот этот json
{
"ok": false,
"error": {
"error_code": 406,
"message": "Please enter [data]."
}
}
Пишем под него модель
public class ApiErrorResponse
{
public bool Ok { get; set; }
public ApiErrorInfo Error { get; set; }
}
public class ApiErrorInfo
{
[JsonProperty("error_code")]
public int Code { get; set; }
public string Message { get; set; }
}
Далее как-то так
using var response = await _httpClient.GetAsync(urlResult);
if (!response.IsSuccessStatusCode)
{
_log.LogWithDetailedInfo($"API error: {(int)response.StatusCode} - {response.ReasonPhrase}");
return null;
}
content = await response.Content.ReadAsStringAsync();
ApiErrorResponse errorResponse = JsonConvert.DeserializeObject<ApiErrorResponse>(content);
if (!errorResponse.Ok)
{
_log.LogWithDetailedInfo($"API error: {errorResponse.Error.Code} - {errorResponse.Error.Message}");
string message = $"Ошибка при обращении в API: {errorResponse.Error.Code} ({errorResponse.Error.Message})";
switch (errorResponse.Error.Code)
{
case 500:
message = "Ошибка подключения к базе данных.";
break;
case 400:
message = "Запрошенная версия API не существует.";
break;
case 401:
message = "Проблема с ключом доступа.";
break;
}
_messageService.ShowOk("ApiClient.Service", message);
return null;
}
// Если всё ошибок нет, продолжаем
ApiCompletedResponse completedResponse = JsonConvert.DeserializeObject<ApiCompletedResponse>(content);
// Продолжаем работать с `completedResponse`