| 12345678910111213141516171819202122232425262728293031323334353637383940414243 |
- using Microsoft.AspNetCore.Diagnostics;
- namespace Web.Api.Common;
- internal sealed class GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger) : IExceptionHandler
- {
- public async ValueTask<bool> TryHandleAsync(
- HttpContext httpContext,
- Exception exception,
- CancellationToken cancellationToken
- ) {
- var (statusCode, message) = exception switch
- {
- BadHttpRequestException => (StatusCodes.Status400BadRequest, "Invalid request body"),
- KeyNotFoundException => (StatusCodes.Status404NotFound, exception.Message),
- InvalidOperationException => (StatusCodes.Status400BadRequest, exception.Message),
- UnauthorizedAccessException => (StatusCodes.Status401Unauthorized, exception.Message),
- // 내부 예외 메시지(EF Core/SQL 등)가 클라이언트로 노출되지 않도록 일반 메시지로 응답. 상세는 아래 LogError 로만 기록.
- _ => (StatusCodes.Status500InternalServerError, "요청 처리 중 오류가 발생했습니다.")
- };
- if (statusCode == StatusCodes.Status500InternalServerError)
- {
- logger.LogError(exception, "Unhandled exception occurred");
- }
- else
- {
- logger.LogWarning(exception, "Handled exception: {Message}", exception.Message);
- }
- httpContext.Response.StatusCode = statusCode;
- httpContext.Response.ContentType = "application/json";
- await httpContext.Response.WriteAsJsonAsync(new ApiResponse
- {
- Success = false,
- Status = statusCode,
- Message = message
- }, cancellationToken);
- return true;
- }
- }
|