Microsoft .NET/ASP.Net & ASP.Net Core
[ASP.NET Core] 전역 예외 처리, IExceptionHandler와 ProblemDetails (.NET 8)
전자기린
2026. 11. 10. 00:47

.NET 8에서 추가된 IExceptionHandler로 예외 응답을 한 곳에서 처리하는 방법입니다. 컨트롤러마다 try-catch를 넣지 않아도 됩니다.
절차
- 핸들러 작성
- 등록
- 응답 형식 확인
- 주의할 점
1. 핸들러 작성
public class GlobalExceptionHandler : IExceptionHandler
{
private readonly ILogger<GlobalExceptionHandler> _logger;
public GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger) => _logger = logger;
public async ValueTask<bool> TryHandleAsync(HttpContext ctx, Exception ex, CancellationToken ct)
{
_logger.LogError(ex, "처리되지 않은 예외: {Path}", ctx.Request.Path);
var (status, title) = ex switch
{
KeyNotFoundException => (StatusCodes.Status404NotFound, "리소스를 찾을 수 없습니다."),
UnauthorizedAccessException => (StatusCodes.Status403Forbidden, "권한이 없습니다."),
_ => (StatusCodes.Status500InternalServerError, "서버 오류가 발생했습니다.")
};
ctx.Response.StatusCode = status;
await ctx.Response.WriteAsJsonAsync(new { title, traceId = ctx.TraceIdentifier }, ct);
return true; // 처리했으면 true
}
}
2. 등록
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler(); // 파이프라인 앞쪽에3. 응답 확인
예외가 나면 아래 형태로 내려갑니다.
{
"title": "서버 오류가 발생했습니다.",
"traceId": "0HN7ABCDEF"
}traceId를 로그와 함께 남기면 사용자 문의 때 바로 찾을 수 있습니다.
4. 주의할 점
UseExceptionHandler()는UseRouting()뒤, 엔드포인트 실행 전에 둡니다- 개발 환경에서는
UseDeveloperExceptionPage()가 먼저 걸려 스택이 보입니다 - 응답을 이미 쓰기 시작한 뒤에는 바꿀 수 없습니다 — 파일 다운로드 중 예외 등
정리
- 핸들러는 예외 타입별로 상태 코드를 매핑
- 등록은
AddExceptionHandler+UseExceptionHandler traceId로 로그와 응답을 연결