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