Files
BQP/srcs/RobotNet10/Components/RobotNet10.NavigationTuneUI/Helpers/ErrorHelper.cs
2026-07-13 09:25:40 +07:00

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;
}
}