ASP.NET Core에서 오류 처리Handle errors in ASP.NET Core

작성자: Steve SmithTom DykstraBy Steve Smith and Tom Dykstra

이 문서에서는 ASP.NET Core 앱에서 오류를 처리하기 위한 일반적인 접근법을 다룹니다.This article covers common approaches to handling errors in ASP.NET Core apps.

예제 코드 살펴보기 및 다운로드(다운로드 방법)View or download sample code (how to download)

개발자 예외 페이지The developer exception page

예외에 대한 자세한 정보를 표시하는 페이지를 표시하는 앱을 구성하려면 개발자 예외 페이지를 사용합니다.To configure an app to display a page that shows detailed information about exceptions, use the developer exception page. Microsoft.AspNetCore.Diagnostics 패키지가 사용할 수 있게 된 페이지는 Microsoft.AspNetCore.App 메타 패키지에서 사용할 수 있습니다.The page made available by the Microsoft.AspNetCore.Diagnostics package, which is available in the Microsoft.AspNetCore.App metapackage. Startup.Configure 메서드에 줄을 추가합니다.Add a line to the Startup.Configure method:

예외에 대한 자세한 정보를 표시하는 페이지를 표시하는 앱을 구성하려면 개발자 예외 페이지를 사용합니다.To configure an app to display a page that shows detailed information about exceptions, use the developer exception page. Microsoft.AspNetCore.Diagnostics 패키지가 사용할 수 있게 된 페이지는 Microsoft.AspNetCore.All 메타 패키지에서 사용할 수 있습니다.The page is made available by the Microsoft.AspNetCore.Diagnostics package, which is available in the Microsoft.AspNetCore.All metapackage. Startup.Configure 메서드에 줄을 추가합니다.Add a line to the Startup.Configure method:

예외에 대한 자세한 정보를 표시하는 페이지를 표시하는 앱을 구성하려면 개발자 예외 페이지를 사용합니다.To configure an app to display a page that shows detailed information about exceptions, use the developer exception page. 프로젝트 파일 내 Microsoft.AspNetCore.Diagnostics 패키지에 대한 패키지 참조를 추가하여 해당 페이지를 사용할 수 있습니다.The page is made available by adding a package reference for the Microsoft.AspNetCore.Diagnostics package in the project file. Startup.Configure 메서드에 줄을 추가합니다.Add a line to the Startup.Configure method:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    env.EnvironmentName = EnvironmentName.Production;

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/error");
    }

app.UseMvc과 같은 예외를 캐치하려는 미들웨어 앞에 UseDeveloperExceptionPage 호출을 둡니다.Place the call to UseDeveloperExceptionPage in front of any middleware where you want to catch exceptions, such as app.UseMvc.

경고

앱이 개발 환경에서 실행 중인 경우에만 개발자 예외 페이지를 사용하도록 설정합니다.Enable the developer exception page only when the app is running in the Development environment. 프로덕션 환경에서 앱을 실행할 때 자세한 예외 정보를 공개적으로 공유하지 않을 수도 있습니다.You don't want to share detailed exception information publicly when the app runs in production. 구성 환경에 대해 자세히 알아보세요.Learn more about configuring environments.

개발자 예외 페이지를 보려면 샘플 앱을 Development로 설정된 환경으로 실행하고, ?throw=true를 앱의 기본 URL에 추가합니다.To see the developer exception page, run the sample app with the environment set to Development, and add ?throw=true to the base URL of the app. 페이지에는 예외 및 요청에 대한 정보가 있는 여러 탭이 포함되어 있습니다.The page includes several tabs with information about the exception and the request. 첫 번째 탭에는 스택 추적이 포함됩니다.The first tab includes a stack trace:

스택 추적

쿼리 문자열 매개 변수가 있는 경우 다음 탭에 표시됩니다.The next tab shows the query string parameters, if any:

쿼리 문자열 매개 변수

요청에 쿠키가 있는 경우 쿠키 탭에 표시됩니다. 헤더는 마지막 탭에 표시됩니다.If the request has cookies, they appear on the Cookies tab. Headers are seen in the last tab:

헤더

사용자 지정 예외 처리 페이지 구성Configuring a custom exception handling page

앱이 Development 환경에서 실행되고 있지 않는 경우 사용할 예외 처리기 페이지를 구성합니다.Configure an exception handler page to use when the app isn't running in the Development environment:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    env.EnvironmentName = EnvironmentName.Production;

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/error");
    }

Razor Pages 앱에서 dotnet new Razor Pages 템플릿은 Pages 폴터의 오류 페이지 및 ErrorModel 페이지 모델 클래스를 제공합니다.In a Razor Pages app, the dotnet new Razor Pages template provides an Error page and ErrorModel page model class in the Pages folder.

MVC 앱에서는 HttpGet과 같은 HTTP 메서드 특성을 사용하여 오류 처리기 작업 메서드를 데코레이트하지 않습니다.In an MVC app, don't decorate the error handler action method with HTTP method attributes, such as HttpGet. 명시적 동사는 일부 요청이 메서드에 도달하지 않도록 방해합니다.Explicit verbs prevent some requests from reaching the method. 인증되지 않은 사용자가 오류 보기를 수신할 수 있도록 메서드에 대한 익명 액세스를 허용합니다.Allow anonymous access to the method so that unauthenticated users are able to receive the error view.

예를 들어 다음 오류 처리기 메서드는 dotnet new MVC 템플릿에서 제공하고 홈 컨트롤러에 표시됩니다.For example, the following error handler method is provided by the dotnet new MVC template and appears in the Home controller:

[AllowAnonymous]
public IActionResult Error()
{
    return View(new ErrorViewModel 
        { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}

상태 코드 페이지 구성Configuring status code pages

기본적으로 앱은 404 찾을 수 없음과 같은 HTTP 상태 코드에 대한 다양한 상태 코드 페이지를 제공하지 않습니다.By default, an app doesn't provide a rich status code page for HTTP status codes, such as 404 Not Found. 상태 코드 페이지를 제공하려면 Startup.Configure 메서드에 줄을 추가하여 상태 코드 페이지 미들웨어를 구성합니다.To provide status code pages, configure the Status Code Pages Middleware by adding a line to the Startup.Configure method:

app.UseStatusCodePages();

기본적으로 상태 코드 페이지 미들웨어는 404와 같은 일반적인 상태 코드에 대한 텍스트 전용 처리기를 추가합니다.By default, Status Code Pages Middleware adds text-only handlers for common status codes, such as 404:

404 페이지

미들웨어는 몇 가지 확장 메서드를 지원합니다.The middleware supports several extension methods. 한 가지 메서드는 람다 식을 사용합니다.One method takes a lambda expression:

app.UseStatusCodePages(async context =>
{
    context.HttpContext.Response.ContentType = "text/plain";

    await context.HttpContext.Response.WriteAsync(
        "Status code page, status code: " + 
        context.HttpContext.Response.StatusCode);
});

또 다른 메서드는 콘텐츠 형식 및 형식 문자열을 사용합니다.Another method takes a content type and format string:

app.UseStatusCodePages("text/plain", "Status code page, status code: {0}");

또한 리디렉션 및 다시 실행 확장 메서드도 있습니다.There's also redirect and re-execute extension methods. 리디렉션 메서드는 302 있음 상태 코드를 클라이언트에 보냅니다.The redirect method sends a 302 Found status code to the client:

app.UseStatusCodePagesWithRedirects("/error/{0}");

다시 실행 메서드는 원래 상태 코드를 클라이언트에 반환할 뿐만 아니라 리디렉션 URL에 대한 처리기도 실행합니다.The re-execute method returns the original status code to the client but also executes the handler for the redirect URL:

app.UseStatusCodePagesWithReExecute("/error/{0}");

Razor 페이지 처리기 메서드 또는 MVC 컨트롤러에서 특정 요청에 대한 상태 코드 페이지를 비활성화할 수 있습니다.Status code pages can be disabled for specific requests in a Razor Pages handler method or in an MVC controller. 상태 코드 페이지를 비활성화하려면 요청의 HttpContext.Features 컬렉션에서 IStatusCodePagesFeature를 검색하고 사용 가능한 경우 기능을 비활성합니다.To disable status code pages, attempt to retrieve the IStatusCodePagesFeature from the request's HttpContext.Features collection and disable the feature if it's available:

var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();

if (statusCodePagesFeature != null)
{
    statusCodePagesFeature.Enabled = false;
}

앱 내에서 엔드포인트를 가리키는 UseStatusCodePages*를 사용하는 경우 엔드포인트에 대해 MVC 보기 또는 Razor Page를 만듭니다.If using a UseStatusCodePages* overload that points to an endpoint within the app, create an MVC view or Razor Page for the endpoint. 예를 들어 Razor Pages 앱의 dotnet new 템플릿은 다음 페이지와 페이지 모델 클래스를 생성합니다.For example, the dotnet new template for a Razor Pages app produces the following page and page model class:

Error.cshtml:Error.cshtml:

@page
@model ErrorModel
@{
    ViewData["Title"] = "Error";
}

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
    <p>
        <strong>Request ID:</strong> <code>@Model.RequestId</code>
    </p>
}

<h3>Development Mode</h3>
<p>
    Swapping to <strong>Development</strong> environment will display more detailed 
    information about the error that occurred.
</p>
<p>
    <strong>Development environment should not be enabled in deployed applications
    </strong>, as it can result in sensitive information from exceptions being 
    displayed to end users. For local debugging, development environment can be 
    enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment 
    variable to <strong>Development</strong>, and restarting the application.
</p>

Error.cshtml.cs:Error.cshtml.cs:

public class ErrorModel : PageModel
{
    public string RequestId { get; set; }

    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, 
        NoStore = true)]
    public void OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
    }
}

예외 처리 코드Exception-handling code

예외 처리 페이지의 코드는 예외를 throw할 수 있습니다.Code in exception handling pages can throw exceptions. 종종 프로덕션 오류 페이지에 대해 완전한 정적 콘텐츠를 구성하는 것이 좋습니다.It's often a good idea for production error pages to consist of purely static content.

또한 일단 응답에 대한 헤더를 보내고 나면 응답의 상태 코드, 예외 페이지 또는 처리기 실행을 변경할 수 없다는 점에 유의하세요.Also, be aware that once the headers for a response have been sent, you can't change the response's status code, nor can any exception pages or handlers run. 응답을 완료하거나 연결이 중단되어야 합니다.The response must be completed or the connection aborted.

서버 예외 처리Server exception handling

앱에서 논리를 처리하는 예외뿐 아니라 앱을 호스팅하는 서버는 몇 가지 예외 처리를 수행합니다.In addition to the exception handling logic in your app, the server hosting your app performs some exception handling. 헤더를 보내기 전에 서버가 예외를 catch하는 경우 서버는 본문이 없는 500 내부 서버 오류 응답을 보냅니다.If the server catches an exception before the headers are sent, the server sends a 500 Internal Server Error response with no body. 헤더를 보낸 후에 서버가 예외를 catch하는 경우 서버는 연결을 닫습니다.If the server catches an exception after the headers have been sent, the server closes the connection. 앱으로 처리되지 않는 요청은 서버에서 처리됩니다.Requests that aren't handled by your app are handled by the server. 발생하는 모든 예외는 서버의 예외 처리에 의해 처리됩니다.Any exception that occurs is handled by the server's exception handling. 구성된 모든 사용자 지정 오류 페이지 또는 예외 처리 미들웨어 또는 필터는 이 동작에 영향을 미치지 않습니다.Any configured custom error pages or exception handling middleware or filters don't affect this behavior.

시작 예외 처리Startup exception handling

호스팅 계층만 앱 시작 시 발생하는 예외를 처리할 수 있습니다.Only the hosting layer can handle exceptions that take place during app startup. 웹 호스트를 사용하면 captureStartupErrorsdetailedErrors 키로 시작 시 오류에 대해 호스트가 응답하는 방법을 구성할 수 있습니다.Using the Web Host, you can configure how the host behaves in response to errors during startup with the captureStartupErrors and detailedErrors keys.

호스팅은 호스트 주소/포트 바인딩 후에 오류가 발생하는 경우 캡처된 시작 오류에 대한 오류 페이지만 표시할 수 있습니다.Hosting can only show an error page for a captured startup error if the error occurs after host address/port binding. 어떤 이유로 바인딩이 실패한 경우 호스팅 계층이 심각한 예외를 기록하고, dotnet 프로세스가 충돌하며, 앱이 Kestrel 서버에서 실행 중일 때 오류 페이지가 표시되지 않습니다.If any binding fails for any reason, the hosting layer logs a critical exception, the dotnet process crashes, and no error page is displayed when the app is running on the Kestrel server.

IIS 또는 IIS Express에서 실행 중일 때, 프로세스를 시작할 수 없는 경우 ASP.NET Core 모듈에서 502.5 프로세스 실패를 반환합니다.When running on IIS or IIS Express, a 502.5 Process Failure is returned by the ASP.NET Core Module if the process can't be started. IIS를 사용하여 호스팅할 때 시작 문제 해결에 대한 내용은 IIS에서 ASP.NET Core 문제 해결을 참조하세요.For information on troubleshooting startup issues when hosting with IIS, see IIS에서 ASP.NET Core 문제 해결. Azure App Service의 시작 문제 해결에 대한 내용은 Azure App Service에서 ASP.NET Core 문제 해결을 참조하세요.For information on troubleshooting startup issues with Azure App Service, see Azure App Service에서 ASP.NET Core 문제 해결.

ASP.NET MVC 오류 처리ASP.NET MVC error handling

MVC 앱에는 예외 필터 구성 및 모델 유효성 검사 수행과 같이 오류를 처리하기 위한 몇 가지 추가 옵션이 있습니다.MVC apps have some additional options for handling errors, such as configuring exception filters and performing model validation.

예외 필터Exception filters

전역으로 또는 MVC 앱에서 컨트롤러당 또는 작업당 기준으로 예외 필터를 구성할 수 있습니다.Exception filters can be configured globally or on a per-controller or per-action basis in an MVC app. 이러한 필터는 컨트롤러 작업 또는 다른 필터를 실행하는 동안 발생하는 처리되지 않은 예외를 처리합니다.These filters handle any unhandled exception that occurs during the execution of a controller action or another filter. 그렇지 않으면 이러한 필터는 호출되지 않습니다.These filters aren't called otherwise. 자세한 내용은 필터를 참조하세요.To learn more, see Filters.

예외 필터는 MVC 작업 내에서 발생하는 예외를 트래핑하는 데 유용하지만 오류 처리 미들웨어만큼 유연하지는 않습니다.Exception filters are good for trapping exceptions that occur within MVC actions, but they're not as flexible as error handling middleware. 일반적인 경우에는 미들웨어를 선호하고, 선택한 MVC 작업에 따라 오류 처리를 다르게 해야 하는 경우에만 필터를 사용합니다.Generally prefer the use of middleware, and use filters only where you need to perform error handling differently based on which MVC action is chosen.

모델 상태 오류 처리Handling model state errors

모델 유효성 검사는 각 컨트롤러 작업을 호출하기 전에 발생하며, ModelState.IsValid를 검사하고 적절하게 반응하는 것은 작업 메서드의 책임입니다.Model validation occurs prior to invoking each controller action, and it's the action method's responsibility to inspect ModelState.IsValid and react appropriately.

필터가 이러한 정책을 구현하기에 적절한 경우에 일부 앱은 모델 유효성 검사 오류를 처리하는 표준 규칙을 따르도록 선택합니다.Some apps choose to follow a standard convention for dealing with model validation errors, in which case a filter may be an appropriate place to implement such a policy. 잘못된 모델 상태일 때 작업 동작 방식을 테스트해야 합니다.You should test how your actions behave with invalid model states. 컨트롤러 논리 테스트에서 자세히 알아보세요.Learn more in Test controller logic.

추가 자료Additional resources