feat: SpmsException 및 글로벌 예외 처리 미들웨어 구현 (#16) #17
50
SPMS.API/Middlewares/ExceptionMiddleware.cs
Normal file
50
SPMS.API/Middlewares/ExceptionMiddleware.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
using SPMS.Domain.Common;
|
||||
using SPMS.Domain.Exceptions;
|
||||
|
||||
namespace SPMS.API.Middlewares;
|
||||
|
||||
public class ExceptionMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ILogger<ExceptionMiddleware> _logger;
|
||||
|
||||
public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger)
|
||||
{
|
||||
_next = next;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
catch (SpmsException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Business exception: {ErrorCode} {Message}", ex.ErrorCode, ex.Message);
|
||||
await HandleSpmsExceptionAsync(context, ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Unhandled exception: {Message}", ex.Message);
|
||||
await HandleUnknownExceptionAsync(context, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task HandleSpmsExceptionAsync(HttpContext context, SpmsException exception)
|
||||
{
|
||||
context.Response.StatusCode = exception.HttpStatusCode;
|
||||
context.Response.ContentType = "application/json";
|
||||
var response = ApiResponse.Fail(exception.ErrorCode, exception.Message);
|
||||
await context.Response.WriteAsJsonAsync(response);
|
||||
}
|
||||
|
||||
private static async Task HandleUnknownExceptionAsync(HttpContext context, Exception exception)
|
||||
{
|
||||
context.Response.StatusCode = 500;
|
||||
context.Response.ContentType = "application/json";
|
||||
var response = ApiResponse.Fail(ErrorCodes.InternalError, "서버 내부 오류가 발생했습니다.");
|
||||
await context.Response.WriteAsJsonAsync(response);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using SPMS.API.Middlewares;
|
||||
using SPMS.Infrastructure;
|
||||
|
||||
|
||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
|
||||
{
|
||||
WebRootPath = Environment.GetEnvironmentVariable("ASPNETCORE_WEBROOT")
|
||||
WebRootPath = Environment.GetEnvironmentVariable("ASPNETCORE_WEBROOT")
|
||||
?? "wwwroot"
|
||||
});
|
||||
|
||||
|
|
@ -19,6 +20,9 @@ builder.Services.AddDbContext<AppDbContext>(options =>
|
|||
|
||||
var app = builder.Build();
|
||||
|
||||
// ── 1. 예외 처리 (최외곽 — 이후 모든 미들웨어 예외 포착) ──
|
||||
app.UseMiddleware<ExceptionMiddleware>();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
|
|
@ -40,7 +44,7 @@ app.UseHttpsRedirection();
|
|||
app.UseRouting();
|
||||
|
||||
// [4] 요청 처리
|
||||
app.MapControllers();
|
||||
app.MapControllers();
|
||||
app.MapFallbackToFile("index.html");
|
||||
|
||||
app.Run();
|
||||
33
SPMS.Domain/Exceptions/SpmsException.cs
Normal file
33
SPMS.Domain/Exceptions/SpmsException.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
using SPMS.Domain.Common;
|
||||
|
||||
namespace SPMS.Domain.Exceptions;
|
||||
|
||||
public class SpmsException : Exception
|
||||
{
|
||||
public string ErrorCode { get; }
|
||||
public int HttpStatusCode { get; }
|
||||
|
||||
public SpmsException(string errorCode, string message, int httpStatusCode = 400)
|
||||
: base(message)
|
||||
{
|
||||
ErrorCode = errorCode;
|
||||
HttpStatusCode = httpStatusCode;
|
||||
}
|
||||
|
||||
// === 팩토리 메서드 ===
|
||||
|
||||
public static SpmsException BadRequest(string message)
|
||||
=> new(ErrorCodes.BadRequest, message, 400);
|
||||
|
||||
public static SpmsException Unauthorized(string message)
|
||||
=> new(ErrorCodes.Unauthorized, message, 401);
|
||||
|
||||
public static SpmsException NotFound(string message)
|
||||
=> new(ErrorCodes.NotFound, message, 404);
|
||||
|
||||
public static SpmsException Conflict(string message)
|
||||
=> new(ErrorCodes.Conflict, message, 409);
|
||||
|
||||
public static SpmsException LimitExceeded(string message)
|
||||
=> new(ErrorCodes.LimitExceeded, message, 429);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user