Initial commit
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user