hrms-api-backend/BMA.EHR.Domain/Middlewares/ErrorHandlerMiddleware.cs

261 lines
9.7 KiB
C#

using BMA.EHR.Domain.Common;
using BMA.EHR.Domain.Shared;
using Microsoft.AspNetCore.Http;
using System.Net;
using System.Text.Json;
namespace BMA.EHR.Domain.Middlewares
{
public class ErrorHandlerMiddleware
{
private readonly RequestDelegate _next;
public ErrorHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
Console.WriteLine("=== ErrorHandlerMiddleware Start ===");
try
{
await _next(context);
Console.WriteLine($"Request completed with status: {context.Response.StatusCode}");
// จัดการ response format หลังจาก request ผ่าน pipeline แล้ว
await FormatResponse(context);
}
catch (ObjectDisposedException)
{
Console.WriteLine("ObjectDisposedException caught in main Invoke");
return;
}
catch (OperationCanceledException)
{
Console.WriteLine("OperationCanceledException caught in main Invoke");
return;
}
catch (Exception error)
{
Console.WriteLine($"Exception caught in main Invoke: {error.Message}");
// จัดการ exception และ format เป็น response
await FormatExceptionResponse(context, error);
}
Console.WriteLine("=== ErrorHandlerMiddleware End ===");
}
private static async Task FormatResponse(HttpContext context)
{
try
{
if (context?.Response == null)
return;
var response = context.Response;
var statusCode = response.StatusCode;
// Debug log
Console.WriteLine($"FormatResponse: StatusCode={statusCode}, HasStarted={response.HasStarted}");
// จัดการเฉพาะ status code ที่ต้องการ format และ response ยังไม่เริ่ม
if (!response.HasStarted && ShouldFormatResponse(statusCode))
{
Console.WriteLine($"Formatting response for status: {statusCode}");
var responseModel = CreateResponseModel(statusCode);
// Clear และตั้งค่าใหม่
response.Clear();
response.StatusCode = statusCode; // เซ็ตกลับไป
response.ContentType = "application/json; charset=utf-8";
var jsonResponse = JsonSerializer.Serialize(responseModel);
await response.WriteAsync(jsonResponse);
Console.WriteLine($"Response formatted successfully: {jsonResponse}");
}
}
catch (ObjectDisposedException)
{
Console.WriteLine("ObjectDisposedException in FormatResponse");
}
catch (Exception ex)
{
Console.WriteLine($"Error in FormatResponse: {ex.Message}");
}
}
private static async Task FormatExceptionResponse(HttpContext context, Exception error)
{
try
{
Console.WriteLine($"FormatExceptionResponse: Error={error.Message}");
if (context?.Response == null)
return;
var response = context.Response;
Console.WriteLine($"Response HasStarted: {response.HasStarted}");
if (!response.HasStarted)
{
// Clear และตั้งค่า response
response.Clear();
response.StatusCode = (int)HttpStatusCode.InternalServerError;
response.ContentType = "application/json; charset=utf-8";
var responseModel = new ResponseObject
{
Status = response.StatusCode,
Message = GlobalMessages.ExceptionOccured,
Result = GetErrorMessage(error)
};
var jsonResponse = JsonSerializer.Serialize(responseModel);
await response.WriteAsync(jsonResponse);
Console.WriteLine($"Exception response formatted: {jsonResponse}");
}
else
{
Console.WriteLine("Cannot format exception response - response already started");
}
}
catch (ObjectDisposedException)
{
Console.WriteLine("ObjectDisposedException in FormatExceptionResponse");
}
catch (Exception ex)
{
Console.WriteLine($"Error in FormatExceptionResponse: {ex.Message}");
}
}
private static bool ShouldFormatResponse(int statusCode)
{
// กำหนด status code ที่ต้องการ format
return statusCode == (int)HttpStatusCode.Unauthorized ||
statusCode == (int)HttpStatusCode.Forbidden ||
statusCode == (int)HttpStatusCode.BadRequest ||
statusCode == (int)HttpStatusCode.NotFound ||
statusCode == (int)HttpStatusCode.Conflict ||
statusCode == (int)HttpStatusCode.UnprocessableEntity ||
statusCode == (int)HttpStatusCode.InternalServerError; // 500
}
private static ResponseObject CreateResponseModel(int statusCode)
{
var message = statusCode switch
{
(int)HttpStatusCode.Unauthorized => GlobalMessages.NotAuthorized,
(int)HttpStatusCode.Forbidden => GlobalMessages.ForbiddenAccess,
(int)HttpStatusCode.BadRequest => "Bad Request",
(int)HttpStatusCode.NotFound => "Resource Not Found",
(int)HttpStatusCode.Conflict => "Conflict",
(int)HttpStatusCode.UnprocessableEntity => "Validation Error",
(int)HttpStatusCode.InternalServerError => GlobalMessages.ExceptionOccured,
_ => "Error"
};
return new ResponseObject
{
Status = statusCode,
Message = message
};
}
private static string GetErrorMessage(Exception error)
{
var msg = error.Message;
var inner = error.InnerException;
while (inner != null)
{
msg += $" {inner.Message}\r\n";
inner = inner.InnerException;
}
return msg;
}
}
}
// using BMA.EHR.Domain.Common;
// using BMA.EHR.Domain.Shared;
// using Microsoft.AspNetCore.Http;
// using System.Net;
//
// namespace BMA.EHR.Domain.Middlewares
// {
// public class ErrorHandlerMiddleware
// {
// private readonly RequestDelegate _next;
//
// public ErrorHandlerMiddleware(RequestDelegate next)
// {
// _next = next;
// }
//
// public async Task Invoke(HttpContext context)
// {
// try
// {
// await _next(context);
//
// var response = context.Response;
// var statusCode = response.StatusCode;
//
// if (!response.HasStarted &&
// (statusCode == (int)HttpStatusCode.Unauthorized || statusCode == (int)HttpStatusCode.Forbidden))
// {
// var responseModel = new ResponseObject
// {
// Status = statusCode,
// Message = statusCode == (int)HttpStatusCode.Unauthorized
// ? GlobalMessages.NotAuthorized
// : GlobalMessages.ForbiddenAccess
// };
//
// response.ContentType = "application/json";
// await response.WriteAsJsonAsync(responseModel);
// }
// }
// catch (Exception error)
// {
// var response = context.Response;
//
// if (!response.HasStarted)
// {
// response.Clear();
// response.ContentType = "application/json";
// response.StatusCode = (int)HttpStatusCode.InternalServerError;
//
// var msg = error.Message;
// var inner = error.InnerException;
// while (inner != null)
// {
// msg += $" {inner.Message}\r\n";
// inner = inner.InnerException;
// }
//
// var responseModel = new ResponseObject
// {
// Status = response.StatusCode,
// Message = GlobalMessages.ExceptionOccured,
// Result = msg
// };
//
// await response.WriteAsJsonAsync(responseModel);
// }
// else
// {
// // logging กรณีที่ response เริ่มถูกส่งแล้ว
// Console.WriteLine("Cannot write error response, stream already started.");
// Console.WriteLine(error);
// }
// }
// }
// }
// }