148 lines
5.9 KiB
C#
148 lines
5.9 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
|
|
namespace RobotNet10.NavigationTuneUI.Helpers;
|
|
|
|
/// <summary>
|
|
/// Helper class for extracting meaningful error messages from HTTP responses
|
|
/// </summary>
|
|
public static class ErrorHelper
|
|
{
|
|
/// <summary>
|
|
/// Extract error message from HTTP response
|
|
/// </summary>
|
|
public static async Task<string> GetErrorMessageAsync(HttpResponseMessage response)
|
|
{
|
|
try
|
|
{
|
|
// Try to read as JSON error object
|
|
var errorObject = await response.Content.ReadFromJsonAsync<JsonElement>();
|
|
|
|
// Check for common error formats
|
|
if (errorObject.ValueKind == JsonValueKind.Object)
|
|
{
|
|
// Format: { error: "message" }
|
|
if (errorObject.TryGetProperty("error", out var errorProp) &&
|
|
errorProp.ValueKind == JsonValueKind.String)
|
|
{
|
|
var errorMessage = errorProp.GetString();
|
|
|
|
// If there's a details field, append it
|
|
if (errorObject.TryGetProperty("details", out var detailsProp) &&
|
|
detailsProp.ValueKind == JsonValueKind.String)
|
|
{
|
|
var details = detailsProp.GetString();
|
|
if (!string.IsNullOrWhiteSpace(details))
|
|
{
|
|
return $"{errorMessage}: {details}";
|
|
}
|
|
}
|
|
|
|
// If there's an errors array (validation errors), append them
|
|
if (errorObject.TryGetProperty("errors", out var errorsProp) &&
|
|
errorsProp.ValueKind == JsonValueKind.Array)
|
|
{
|
|
var errors = errorsProp.EnumerateArray()
|
|
.Where(e => e.ValueKind == JsonValueKind.String)
|
|
.Select(e => e.GetString())
|
|
.Where(s => !string.IsNullOrWhiteSpace(s))
|
|
.ToList();
|
|
|
|
if (errors.Count > 0)
|
|
{
|
|
return $"{errorMessage}\n{string.Join("\n", errors)}";
|
|
}
|
|
}
|
|
|
|
return errorMessage ?? GetDefaultErrorMessage(response.StatusCode);
|
|
}
|
|
|
|
// Format: { message: "message" }
|
|
if (errorObject.TryGetProperty("message", out var messageProp) &&
|
|
messageProp.ValueKind == JsonValueKind.String)
|
|
{
|
|
return messageProp.GetString() ?? GetDefaultErrorMessage(response.StatusCode);
|
|
}
|
|
}
|
|
|
|
// Try to read as plain text
|
|
var textContent = await response.Content.ReadAsStringAsync();
|
|
if (!string.IsNullOrWhiteSpace(textContent))
|
|
{
|
|
return textContent;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
// If parsing fails, fall back to status code message
|
|
}
|
|
|
|
return GetDefaultErrorMessage(response.StatusCode);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get default error message based on HTTP status code
|
|
/// </summary>
|
|
private static string GetDefaultErrorMessage(HttpStatusCode statusCode)
|
|
{
|
|
return statusCode switch
|
|
{
|
|
HttpStatusCode.BadRequest => "Yêu cầu không hợp lệ. Vui lòng kiểm tra lại dữ liệu đầu vào.",
|
|
HttpStatusCode.Unauthorized => "Bạn chưa được xác thực. Vui lòng đăng nhập lại.",
|
|
HttpStatusCode.Forbidden => "Bạn không có quyền thực hiện thao tác này.",
|
|
HttpStatusCode.NotFound => "Không tìm thấy tài nguyên yêu cầu.",
|
|
HttpStatusCode.Conflict => "Xung đột dữ liệu. Có thể tài nguyên đã tồn tại.",
|
|
HttpStatusCode.InternalServerError => "Lỗi máy chủ. Vui lòng thử lại sau.",
|
|
HttpStatusCode.ServiceUnavailable => "Dịch vụ tạm thời không khả dụng. Vui lòng thử lại sau.",
|
|
HttpStatusCode.RequestTimeout => "Yêu cầu quá thời gian chờ. Vui lòng thử lại.",
|
|
_ => $"Lỗi không xác định ({(int)statusCode} {statusCode})"
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract error message from exception
|
|
/// </summary>
|
|
public static string GetErrorMessage(Exception ex)
|
|
{
|
|
// For HttpRequestException, try to extract more meaningful message
|
|
if (ex is HttpRequestException httpEx)
|
|
{
|
|
// Check if it's a connection error
|
|
if (httpEx.Message.Contains("connection") || httpEx.Message.Contains("refused"))
|
|
{
|
|
return "Không thể kết nối đến máy chủ. Vui lòng kiểm tra kết nối mạng.";
|
|
}
|
|
|
|
// Check if it's a timeout
|
|
if (httpEx.Message.Contains("timeout"))
|
|
{
|
|
return "Yêu cầu quá thời gian chờ. Vui lòng thử lại.";
|
|
}
|
|
|
|
return httpEx.Message;
|
|
}
|
|
|
|
// For TaskCanceledException (often timeout)
|
|
if (ex is TaskCanceledException)
|
|
{
|
|
return "Yêu cầu quá thời gian chờ. Vui lòng thử lại.";
|
|
}
|
|
|
|
// For JsonException
|
|
if (ex is JsonException)
|
|
{
|
|
return "Lỗi xử lý dữ liệu từ máy chủ. Vui lòng thử lại.";
|
|
}
|
|
|
|
// For InvalidOperationException
|
|
if (ex is InvalidOperationException)
|
|
{
|
|
return ex.Message;
|
|
}
|
|
|
|
// Default: return exception message
|
|
return ex.Message;
|
|
}
|
|
}
|