최소 API 앱에서 오류를 처리하는 방법
참고 항목
이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.
Important
이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.
현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.
데이비드 애커의 기여와 함께
이 문서에서는 최소 API 앱에서 오류를 처리하는 방법을 설명합니다. 컨트롤러 기반 API 의 오류 처리에 대한 자세한 내용은 ASP.NET Core 의 오류 처리 및 ASP.NET Core 컨트롤러 기반 웹 API의 오류 처리를 참조하세요.
예외
최소 API 앱에는 처리되지 않은 예외를 처리하는 두 가지 기본 제공 중앙 집중식 메커니즘이 있습니다.
- 개발자 예외 페이지 미들웨어(개발 환경에서만 사용)
- 예외 처리기 미들웨어
이 섹션에서는 최소 API에서 예외를 처리하는 방법을 보여 주는 다음 샘플 앱을 참조합니다. 엔드포인트 /exception
가 요청되면 예외를 throw합니다.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/exception", () =>
{
throw new InvalidOperationException("Sample Exception");
});
app.MapGet("/", () => "Test by calling /exception");
app.Run();
개발자 예외 페이지
개발자 예외 페이지에는 처리되지 않은 요청 예외에 대한 자세한 정보가 표시됩니다. 이것은 DeveloperExceptionPageMiddleware를 사용하여 HTTP 파이프라인에서 동기 및 비동기 예외를 캡처하고 오류 응답을 생성합니다. 개발자 예외 페이지는 미들웨어 파이프라인의 앞부분에 실행되므로, 다음에 오는 미들웨어에서 throw된 미처리 예외를 catch할 수 있습니다.
ASP.NET Core 앱은 다음과 같은 경우 기본적으로 개발자 예외 페이지를 사용할 수 있습니다.
- 개발 환경에서 실행합니다.
- 앱은 현재 템플릿, 즉 WebApplication.CreateBuilder.
이전 템플릿을 사용하여 만든 앱, 즉, 사용하여 WebHost.CreateDefaultBuilder개발자 예외 페이지를 호출 app.UseDeveloperExceptionPage
하여 사용하도록 설정할 수 있습니다.
Warning
앱이 개발 환경에서 실행 중인 경우에만 개발자 예외 페이지를 사용하도록 설정하지 마세요. 프로덕션 환경에서 앱을 실행할 때 자세한 예외 정보를 공개적으로 공유하지 마세요. 환경을 구성하는 방법에 대한 자세한 내용은 ASP.NET Core에서 여러 환경 사용을 참조하세요.
개발자 예외 페이지에는 예외 및 요청에 대한 다음 정보가 포함될 수 있습니다.
- 스택 추적
- 쿼리 문자열 매개 변수(있는 경우)
- 쿠키(있는 경우)
- 머리글
- 엔드포인트 메타데이터(있는 경우)
개발자 예외 페이지는 어떠한 정보 제공도 보장하지 않습니다. 전체 오류 정보를 보려면 로깅을 사용하세요.
다음 이미지는 탭 및 표시되는 정보를 표시하는 애니메이션이 있는 샘플 개발자 예외 페이지를 보여 줍니다.
헤더가 있는 요청에 Accept: text/plain
대한 응답으로 개발자 예외 페이지는 HTML 대신 일반 텍스트를 반환합니다. 예시:
Status: 500 Internal Server Error
Time: 9.39 msSize: 480 bytes
FormattedRawHeadersRequest
Body
text/plain; charset=utf-8, 480 bytes
System.InvalidOperationException: Sample Exception
at WebApplicationMinimal.Program.<>c.<Main>b__0_0() in C:\Source\WebApplicationMinimal\Program.cs:line 12
at lambda_method1(Closure, Object, HttpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
HEADERS
=======
Accept: text/plain
Host: localhost:7267
traceparent: 00-0eab195ea19d07b90a46cd7d6bf2f
개발자 예외 페이지를 보려면:
- 개발 환경에서 샘플 앱을 실행합니다.
- 엔드포인트로
/exception
이동합니다.
예외 처리기
비개발 환경에서는 예외 처리 미들웨어를 사용하여 오류 페이로드를 생성할 수 있습니다. Exception Handler Middleware
를 구성하려면 UseExceptionHandler를 호출합니다.
예를 들어 다음 코드는 RFC 7807 규격 페이로드로 클라이언트에 응답하도록 앱을 변경합니다. 자세한 내용은 이 문서의 뒷부분에 있는 문제 세부 정보 섹션을 참조하세요.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseExceptionHandler(exceptionHandlerApp
=> exceptionHandlerApp.Run(async context
=> await Results.Problem()
.ExecuteAsync(context)));
app.MapGet("/exception", () =>
{
throw new InvalidOperationException("Sample Exception");
});
app.MapGet("/", () => "Test by calling /exception");
app.Run();
클라이언트 및 서버 오류 응답
다음 최소 API 앱을 고려합니다.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)));
app.MapGet("/", () => "Test by calling /users/{id:int}");
app.Run();
public record User(int Id);
/users
엔드포인트는 id
가 0
보다 크면 User
를 나타내는 json
과 함께 200 OK
를 생성하고, 그렇지 않으면 응답 본문이 없는 400 BAD REQUEST
상태 코드를 생성합니다. 응답을 만드는 방법에 대한 자세한 내용은 최소 API 앱에서 응답 만들기를 참조하세요.
Status Code Pages middleware
는 모든 HTTP 클라이언트(400
-499
) 또는 서버(500
-599
) 응답에 대해 비어 있는 경우, 공용 본문 콘텐츠를 생성하도록 구성할 수 있습니다. 미들웨어는 UseStatusCodePages 확장 메서드를 호출하여 구성됩니다.
예를 들어, 다음 예제에서는 라우팅 오류(예: 404 NOT FOUND
)를 포함하여 모든 클라이언트 및 서버 응답에 대해 RFC 7807 규격 페이로드로 응답하도록 앱을 클라이언트로 변경합니다. 자세한 내용은 문제 세부 정보 섹션을 참조하세요.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseStatusCodePages(async statusCodeContext
=> await Results.Problem(statusCode: statusCodeContext.HttpContext.Response.StatusCode)
.ExecuteAsync(statusCodeContext.HttpContext));
app.MapGet("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) );
app.MapGet("/", () => "Test by calling /users/{id:int}");
app.Run();
public record User(int Id);
문제 세부 정보
문제 세부 정보는 HTTP API 오류를 설명하는 유일한 응답 형식은 아니지만 일반적으로 HTTP API에 대한 오류를 보고하는 데 사용됩니다.
문제 세부 정보 서비스는 ASP.NET Core 문제 세부 정보 만들기를 지원하는 IProblemDetailsService 인터페이스를 구현합니다. IServiceCollection의 AddProblemDetails(IServiceCollection) 확장 메서드는 기본 IProblemDetailsService
구현을 등록합니다.
ASP.NET Core 앱에서 다음 미들웨어는 Accept
이 등록된 IProblemDetailsWriter(기본값: application/json
)가 지원되는 콘텐츠 형식 중 하나가 포함되지 않은 HTTP 헤더를 요청하는 경우를 제외하고 AddProblemDetails
가 호출될 때 문제 세부 정보 HTTP 응답을 생성합니다.
- ExceptionHandlerMiddleware: 사용자 지정 처리기가 정의되지 않은 경우 문제 세부 정보 응답을 생성합니다.
- StatusCodePagesMiddleware: 기본적으로 문제 세부 정보 응답을 생성합니다.
- DeveloperExceptionPageMiddleware: 요청 HTTP 헤더에 포함되지
text/html
않은 경우 개발 시Accept
문제 세부 정보 응답을 생성합니다.
확장 메서드를 사용하여 AddProblemDetails
아직 본문 콘텐츠가 없는 모든 HTTP 클라이언트 및 서버 오류 응답에 대한 문제 세부 정보 응답을 생성하도록 최소 API 앱을 구성할 수 있습니다.
다음 코드는 문제 세부 정보를 생성하도록 앱을 구성합니다.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
app.MapGet("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)));
app.MapGet("/", () => "Test by calling /users/{id:int}");
app.Run();
public record User(int Id);
AddProblemDetails
사용에 대한 자세한 내용은 문제 세부 정보를 참조하세요.
IProblemDetailsService 대체
다음 코드 httpContext.Response.WriteAsync("Fallback: An error occurred.")
에서는 구현에서 다음을 생성할 수 없는 경우 IProblemDetailsService 오류를 반환합니다.ProblemDetails
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async httpContext =>
{
var pds = httpContext.RequestServices.GetService<IProblemDetailsService>();
if (pds == null
|| !await pds.TryWriteAsync(new() { HttpContext = httpContext }))
{
// Fallback behavior
await httpContext.Response.WriteAsync("Fallback: An error occurred.");
}
});
});
app.MapGet("/exception", () =>
{
throw new InvalidOperationException("Sample Exception");
});
app.MapGet("/", () => "Test by calling /exception");
app.Run();
앞의 코드가 하는 역할은 다음과 같습니다.
- 를 쓸 수 없는 경우
problemDetailsService
대체 코드와 함께 오류 메시지를 씁니다ProblemDetails
. 예를 들어 Accept 요청 헤더가 지원하지 않는 미디어 형식을 지정하는DefaulProblemDetailsWriter
엔드포인트입니다. - 예외 처리기 미들웨어를 사용합니다.
다음 샘플은 을 호출한다는 점을 제외하고 이전 샘플과 Status Code Pages middleware
유사합니다.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseStatusCodePages(statusCodeHandlerApp =>
{
statusCodeHandlerApp.Run(async httpContext =>
{
var pds = httpContext.RequestServices.GetService<IProblemDetailsService>();
if (pds == null
|| !await pds.TryWriteAsync(new() { HttpContext = httpContext }))
{
// Fallback behavior
await httpContext.Response.WriteAsync("Fallback: An error occurred.");
}
});
});
app.MapGet("/users/{id:int}", (int id) =>
{
return id <= 0 ? Results.BadRequest() : Results.Ok(new User(id));
});
app.MapGet("/", () => "Test by calling /users/{id:int}");
app.Run();
public record User(int Id);
이 문서에서는 최소 API 앱에서 오류를 처리하는 방법을 설명합니다.
예외
최소 API 앱에는 처리되지 않은 예외를 처리하는 두 가지 기본 제공 중앙 집중식 메커니즘이 있습니다.
- 개발자 예외 페이지 미들웨어(개발 환경에서만 사용)
- 예외 처리기 미들웨어
이 섹션에서는 예외를 처리하는 방법을 보여주는 다음 최소 API 앱을 참조합니다. 엔드포인트 /exception
가 요청되면 예외를 throw합니다.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Map("/exception", ()
=> { throw new InvalidOperationException("Sample Exception"); });
app.Run();
개발자 예외 페이지
개발자 예외 페이지에는 서버 오류에 대한 자세한 스택 추적이 표시됩니다. 이것은 DeveloperExceptionPageMiddleware를 사용하여 HTTP 파이프라인에서 동기 및 비동기 예외를 캡처하고 오류 응답을 생성합니다.
ASP.NET Core 앱은 다음과 같은 경우 기본적으로 개발자 예외 페이지를 사용할 수 있습니다.
- 개발 환경에서 실행합니다.
- 앱은 WebApplication.CreateBuilder를 사용하고 있습니다.
미들웨어 구성에 대한 자세한 내용은 최소 API 앱의 미들웨어를 참조하세요.
위의 최소 API 앱을 사용하여 Developer Exception Page
가 처리되지 않은 예외를 검색하면 다음 예제와 유사한 기본 일반 텍스트 응답이 생성됩니다.
HTTP/1.1 500 Internal Server Error
Content-Type: text/plain; charset=utf-8
Date: Thu, 27 Oct 2022 18:00:59 GMT
Server: Kestrel
Transfer-Encoding: chunked
System.InvalidOperationException: Sample Exception
at Program.<>c.<<Main>$>b__0_1() in ....:line 17
at lambda_method2(Closure, Object, HttpContext)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
HEADERS
=======
Accept: */*
Connection: keep-alive
Host: localhost:5239
Accept-Encoding: gzip, deflate, br
Warning
앱이 개발 환경에서 실행 중인 경우에만 개발자 예외 페이지를 사용하도록 설정하지 마세요. 프로덕션 환경에서 앱을 실행할 때 자세한 예외 정보를 공개적으로 공유하지 마세요. 환경을 구성하는 방법에 대한 자세한 내용은 ASP.NET Core에서 여러 환경 사용을 참조하세요.
예외 처리기
비개발 환경에서는 예외 처리 미들웨어를 사용하여 오류 페이로드를 생성할 수 있습니다. Exception Handler Middleware
를 구성하려면 UseExceptionHandler를 호출합니다.
예를 들어 다음 코드는 RFC 7807 규격 페이로드로 클라이언트에 응답하도록 앱을 변경합니다. 자세한 내용은 문제 세부 정보 섹션을 참조하세요.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseExceptionHandler(exceptionHandlerApp
=> exceptionHandlerApp.Run(async context
=> await Results.Problem()
.ExecuteAsync(context)));
app.Map("/exception", ()
=> { throw new InvalidOperationException("Sample Exception"); });
app.Run();
클라이언트 및 서버 오류 응답
다음 최소 API 앱을 고려합니다.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Map("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) );
app.Run();
public record User(int Id);
/users
엔드포인트는 id
가 0
보다 크면 User
를 나타내는 json
과 함께 200 OK
를 생성하고, 그렇지 않으면 응답 본문이 없는 400 BAD REQUEST
상태 코드를 생성합니다. 응답을 만드는 방법에 대한 자세한 내용은 최소 API 앱에서 응답 만들기를 참조하세요.
Status Code Pages middleware
는 모든 HTTP 클라이언트(400
-499
) 또는 서버(500
-599
) 응답에 대해 비어 있는 경우, 공용 본문 콘텐츠를 생성하도록 구성할 수 있습니다. 미들웨어는 UseStatusCodePages 확장 메서드를 호출하여 구성됩니다.
예를 들어, 다음 예제에서는 라우팅 오류(예: 404 NOT FOUND
)를 포함하여 모든 클라이언트 및 서버 응답에 대해 RFC 7807 규격 페이로드로 응답하도록 앱을 클라이언트로 변경합니다. 자세한 내용은 문제 세부 정보 섹션을 참조하세요.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseStatusCodePages(async statusCodeContext
=> await Results.Problem(statusCode: statusCodeContext.HttpContext.Response.StatusCode)
.ExecuteAsync(statusCodeContext.HttpContext));
app.Map("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) );
app.Run();
public record User(int Id);
문제 세부 정보
문제 세부 정보는 HTTP API 오류를 설명하는 유일한 응답 형식은 아니지만 일반적으로 HTTP API에 대한 오류를 보고하는 데 사용됩니다.
문제 세부 정보 서비스는 ASP.NET Core 문제 세부 정보 만들기를 지원하는 IProblemDetailsService 인터페이스를 구현합니다. IServiceCollection의 AddProblemDetails(IServiceCollection) 확장 메서드는 기본 IProblemDetailsService
구현을 등록합니다.
ASP.NET Core 앱에서 다음 미들웨어는 Accept
이 등록된 IProblemDetailsWriter(기본값: application/json
)가 지원되는 콘텐츠 형식 중 하나가 포함되지 않은 HTTP 헤더를 요청하는 경우를 제외하고 AddProblemDetails
가 호출될 때 문제 세부 정보 HTTP 응답을 생성합니다.
- ExceptionHandlerMiddleware: 사용자 지정 처리기가 정의되지 않은 경우 문제 세부 정보 응답을 생성합니다.
- StatusCodePagesMiddleware: 기본적으로 문제 세부 정보 응답을 생성합니다.
- DeveloperExceptionPageMiddleware: 요청 HTTP 헤더에 포함되지
text/html
않은 경우 개발 시Accept
문제 세부 정보 응답을 생성합니다.
최소 API 앱은 AddProblemDetails
확장 메서드를 사용하여 아직 본문 콘텐츠가 없는 모든 HTTP 클라이언트 및 서버 오류 응답에 대한 문제 세부 정보 응답을 생성하도록 구성할 수 있습니다.
다음 코드는 문제 세부 정보를 생성하도록 앱을 구성합니다.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
app.Map("/users/{id:int}", (int id)
=> id <= 0 ? Results.BadRequest() : Results.Ok(new User(id)) );
app.Map("/exception", ()
=> { throw new InvalidOperationException("Sample Exception"); });
app.Run();
AddProblemDetails
사용에 대한 자세한 내용은 문제 세부 정보를 참조하세요.
ASP.NET Core