Tratar erros no ASP.NET CoreHandle errors in ASP.NET Core

Por Tom Dykstra, Luke Latham e Steve SmithBy Tom Dykstra, Luke Latham, and Steve Smith

Este artigo aborda abordagens comuns para lidar com erros em ASP.NET Core aplicativos Web.This article covers common approaches to handling errors in ASP.NET Core web apps. Consulte Tratar erros em APIs da Web ASP.NET Core para APIs da Web.See Tratar erros em APIs da Web ASP.NET Core for web APIs.

Exibir ou baixar o código de exemplo.View or download sample code. (Como baixar.) O artigo inclui instruções sobre como definir diretivas de pré-processador (#if, #endif, #define) no aplicativo de exemplo para habilitar cenários diferentes.(How to download.) The article includes instructions about how to set preprocessor directives (#if, #endif, #define) in the sample app to enable different scenarios.

Página de exceção do desenvolvedorDeveloper Exception Page

A Página de exceção do desenvolvedor exibe informações detalhadas sobre as exceções de solicitação.The Developer Exception Page displays detailed information about request exceptions. A página é disponibilizada pelo pacote Microsoft.AspNetCore.Diagnostics, que está no metapacote Microsoft.AspNetCore.App.The page is made available by the Microsoft.AspNetCore.Diagnostics package, which is in the Microsoft.AspNetCore.App metapackage. Adicione código ao método Startup.Configure para habilitar a página quando o aplicativo estiver sendo executado no ambiente de desenvolvimento:Add code to the Startup.Configure method to enable the page when the app is running in the Development environment:

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

Coloque a chamada para UseDeveloperExceptionPage antes de qualquer middleware no qual você deseja capturar exceções.Place the call to UseDeveloperExceptionPage before any middleware that you want to catch exceptions.

Aviso

Habilite a página de exceção do desenvolvedor somente quando o aplicativo estiver em execução no ambiente de desenvolvimento.Enable the Developer Exception Page only when the app is running in the Development environment. Não é recomendável compartilhar informações de exceção detalhadas publicamente quando o aplicativo é executado em produção.You don't want to share detailed exception information publicly when the app runs in production. Para saber mais sobre a configuração de ambientes, confira Usar vários ambientes no ASP.NET Core.For more information on configuring environments, see Usar vários ambientes no ASP.NET Core.

A página inclui as seguintes informações sobre a exceção e a solicitação:The page includes the following information about the exception and the request:

  • Rastreamento de pilhaStack trace
  • Parâmetros de cadeia de caracteres de consulta (se houver algum)Query string parameters (if any)
  • Cookies (se houver algum)Cookies (if any)
  • CabeçalhosHeaders

Para ver a Página de exceção do desenvolvedor no aplicativo de exemplo, use a diretiva de pré-processador DevEnvironment e selecione Disparar uma exceção na página inicial.To see the Developer Exception Page in the sample app, use the DevEnvironment preprocessor directive and select Trigger an exception on the home page.

Página do Manipulador de exceçãoException handler page

Use o Middleware de tratamento de exceção para configurar uma página personalizada de tratamento de erro para o ambiente de produção.To configure a custom error handling page for the Production environment, use the Exception Handling Middleware. O middleware:The middleware:

  • Captura e registra em log as exceções.Catches and logs exceptions.
  • Executa novamente a solicitação em um pipeline alternativo para a página ou controlador indicado.Re-executes the request in an alternate pipeline for the page or controller indicated. A solicitação não será executada novamente se a resposta tiver sido iniciada.The request isn't re-executed if the response has started.

No exemplo a seguir, UseExceptionHandler inclui o Middleware de Manipulação de Exceções em ambientes que não são de desenvolvimento:In the following example, UseExceptionHandler adds the Exception Handling Middleware in non-Development environments:

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

O modelo de aplicativo Razor Pages fornece uma Página de erro ( .cshtml) e uma classe PageModel (ErrorModel) na pasta Páginas.The Razor Pages app template provides an Error page (.cshtml) and PageModel class (ErrorModel) in the Pages folder. Para um aplicativo MVC, o modelo de projeto inclui um Método de ação de erro e uma Exibição de erro.For an MVC app, the project template includes an Error action method and an Error view. Este é o método de ação:Here's the action method:

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

Não decore o método de ação do manipulador de erro com atributos de método HTTP, como HttpGet.Don't decorate the error handler action method with HTTP method attributes, such as HttpGet. Verbos explícitos impedem algumas solicitações de chegar ao método.Explicit verbs prevent some requests from reaching the method. Permita acesso anônimo ao método para que os usuários não autenticados possam capazes receber a exibição de erro.Allow anonymous access to the method so that unauthenticated users are able to receive the error view.

Acessar a exceçãoAccess the exception

Use IExceptionHandlerPathFeature para acessar a exceção e o caminho de solicitação original em uma página ou controlador de manipulador de erro:Use IExceptionHandlerPathFeature to access the exception and the original request path in an error handler controller or page:

var exceptionHandlerPathFeature =
    HttpContext.Features.Get<IExceptionHandlerPathFeature>();
if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
{
    ExceptionMessage = "File error thrown";
}
if (exceptionHandlerPathFeature?.Path == "/index")
{
    ExceptionMessage += " from home page";
}

Aviso

Não forneça informações de erro confidenciais aos clientes.Do not serve sensitive error information to clients. Fornecer erros é um risco à segurança.Serving errors is a security risk.

Para ver a página de tratamento de exceções no aplicativo de exemplo, use as diretivas de pré-processador ProdEnvironment e ErrorHandlerPage e selecione Disparar uma exceção na página inicial.To see the exception handling page in the sample app, use the ProdEnvironment and ErrorHandlerPage preprocessor directives, and select Trigger an exception on the home page.

Lambda do Manipulador de exceçãoException handler lambda

Uma alternativa a uma página personalizada de manipulador de exceção é fornecer um lambda a UseExceptionHandler.An alternative to a custom exception handler page is to provide a lambda to UseExceptionHandler. Usar um lambda permite acessar o erro antes de retornar a resposta.Using a lambda allows access to the error before returning the response.

Este é um exemplo de como usar um lambda para a manipulação de exceção:Here's an example of using a lambda for exception handling:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
   app.UseExceptionHandler(errorApp =>
   {
        errorApp.Run(async context =>
        {
            context.Response.StatusCode = 500;
            context.Response.ContentType = "text/html";

            await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
            await context.Response.WriteAsync("ERROR!<br><br>\r\n");

            var exceptionHandlerPathFeature = 
                context.Features.Get<IExceptionHandlerPathFeature>();

            // Use exceptionHandlerPathFeature to process the exception (for example, 
            // logging), but do NOT expose sensitive error information directly to 
            // the client.

            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
                await context.Response.WriteAsync("File error thrown!<br><br>\r\n");
            }

            await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n");
            await context.Response.WriteAsync("</body></html>\r\n");
            await context.Response.WriteAsync(new string(' ', 512)); // IE padding
        });
    });
    app.UseHsts();
}

Aviso

Não forneça informações de erro confidenciais de IExceptionHandlerFeature ou IExceptionHandlerPathFeature para clientes.Do not serve sensitive error information from IExceptionHandlerFeature or IExceptionHandlerPathFeature to clients. Fornecer erros é um risco à segurança.Serving errors is a security risk.

Para ver o resultado do lambda de tratamento de exceções no aplicativo de exemplo, use as diretivas de pré-processador ProdEnvironment e ErrorHandlerLambda e selecione Disparar uma exceção na página inicial.To see the result of the exception handling lambda in the sample app, use the ProdEnvironment and ErrorHandlerLambda preprocessor directives, and select Trigger an exception on the home page.

UseStatusCodePagesUseStatusCodePages

Por padrão, o aplicativo ASP.NET Core não fornece uma página de código de status para códigos de status HTTP, como 404 - Não Encontrado.By default, an ASP.NET Core app doesn't provide a status code page for HTTP status codes, such as 404 - Not Found. O aplicativo retornar um código de status e um corpo de resposta vazio.The app returns a status code and an empty response body. Use o middleware das Páginas de código de status para fornecer páginas de código de status.To provide status code pages, use Status Code Pages middleware.

O middleware é disponibilizado pelo pacote Microsoft.AspNetCore.Diagnostics, que está no metapacote Microsoft.AspNetCore.App.The middleware is made available by the Microsoft.AspNetCore.Diagnostics package, which is in the Microsoft.AspNetCore.App metapackage.

Para habilitar os manipuladores padrão somente texto para os códigos de status de erros comuns, chame UseStatusCodePages no método Startup.Configure:To enable default text-only handlers for common error status codes, call UseStatusCodePages in the Startup.Configure method:

app.UseStatusCodePages();

Chame UseStatusCodePages antes do middleware de tratamento da solicitação (por exemplo, o middleware de arquivos estáticos e o middleware MVC).Call UseStatusCodePages before request handling middleware (for example, Static File Middleware and MVC Middleware).

Este é um exemplo de texto exibido pelos manipuladores padrão:Here's an example of text displayed by the default handlers:

Status Code: 404; Not Found

Para ver um dos diversos formatos de páginas de código de status no aplicativo de exemplo, use uma das diretivas de pré-processador que começam com StatusCodePages e selecione Disparar um 404 na página inicial.To see one of the various status code page formats in the sample app, use one of the preprocessor directives that begin with StatusCodePages, and select Trigger a 404 on the home page.

UseStatusCodePages com cadeia de caracteres de formatoUseStatusCodePages with format string

Para personalizar o texto e o tipo de conteúdo de resposta, use uma sobrecarga de UseStatusCodePages que leva um tipo de conteúdo e uma cadeia de caracteres de formato:To customize the response content type and text, use the overload of UseStatusCodePages that takes a content type and format string:

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

UseStatusCodePages com lambdaUseStatusCodePages with lambda

Para especificar a manipulação de erro personalizada e o código de gravação de resposta, use a sobrecarga de UseStatusCodePages que leva uma expressão lambda:To specify custom error-handling and response-writing code, use the overload of UseStatusCodePages that 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);
});

UseStatusCodePagesWithRedirectsUseStatusCodePagesWithRedirects

O método de extensão UseStatusCodePagesWithRedirects:The UseStatusCodePagesWithRedirects extension method:

  • Envia um código de status 302 – Encontrado ao cliente.Sends a 302 - Found status code to the client.
  • Redireciona o cliente para o local fornecido no modelo de URL.Redirects the client to the location provided in the URL template.
app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}");

O modelo de URL pode incluir um espaço reservado {0} para o código de status, conforme mostrado no exemplo.The URL template can include a {0} placeholder for the status code, as shown in the example. Se o modelo de URL começar com um til (~), este será substituído pelo PathBase do aplicativo.If the URL template starts with a tilde (~), the tilde is replaced by the app's PathBase. Se você apontar para um ponto de extremidade dentro do aplicativo, crie um modo de exibição do MVC ou Razor Page para o ponto de extremidade.If you point to an endpoint within the app, create an MVC view or Razor page for the endpoint. Consulte um exemplo de Razor Pages em Pages/StatusCode.cshtml no aplicativo de exemplo.For a Razor Pages example, see Pages/StatusCode.cshtml in the sample app.

Este método normalmente é usado quando o aplicativo:This method is commonly used when the app:

  • Deveria redirecionar o cliente para um terminal diferente, geralmente em situações nas quais um aplicativo diferente processa o erro.Should redirect the client to a different endpoint, usually in cases where a different app processes the error. Para aplicativos Web, a barra de endereços do navegador do cliente reflete o ponto de extremidade redirecionado.For web apps, the client's browser address bar reflects the redirected endpoint.
  • Não deveria preservar e retornar o código de status original com a resposta de redirecionamento inicial.Shouldn't preserve and return the original status code with the initial redirect response.

UseStatusCodePagesWithReExecuteUseStatusCodePagesWithReExecute

O método de extensão UseStatusCodePagesWithReExecute:The UseStatusCodePagesWithReExecute extension method:

  • Retorna o código de status original ao cliente.Returns the original status code to the client.
  • Gera o corpo da resposta ao executar novamente o pipeline de solicitação por meio de um caminho alternativo.Generates the response body by re-executing the request pipeline using an alternate path.
app.UseStatusCodePagesWithReExecute("/StatusCode","?code={0}");

Se você apontar para um ponto de extremidade dentro do aplicativo, crie um modo de exibição do MVC ou Razor Page para o ponto de extremidade.If you point to an endpoint within the app, create an MVC view or Razor page for the endpoint. Consulte um exemplo de Razor Pages em Pages/StatusCode.cshtml no aplicativo de exemplo.For a Razor Pages example, see Pages/StatusCode.cshtml in the sample app.

Este método normalmente é usado quando o aplicativo tem que:This method is commonly used when the app should:

  • Processar a solicitação sem redirecionar para um ponto de extremidade diferente.Process the request without redirecting to a different endpoint. Para aplicativos Web, a barra de endereços do navegador do cliente reflete o ponto de extremidade originalmente solicitado.For web apps, the client's browser address bar reflects the originally requested endpoint.
  • Preservar e retornar o código de status original com a resposta.Preserve and return the original status code with the response.

Os modelos de URL e cadeia de caracteres de consulta podem incluir um espaço reservado ({0}) para o código de status.The URL and query string templates may include a placeholder ({0}) for the status code. O modelo de URL deve começar com uma barra (/).The URL template must start with a slash (/). Ao usar um espaço reservado no caminho, verifique se o ponto de extremidade (página ou controlador) pode processar o segmento de linha.When using a placeholder in the path, confirm that the endpoint (page or controller) can process the path segment. Por exemplo, uma Página do Razor para erros deve aceitar o valor de segmento de linha opcional com a diretiva @page:For example, a Razor Page for errors should accept the optional path segment value with the @page directive:

@page "{code?}"

O ponto de extremidade que processa o erro pode obter a URL original que gerou o erro, conforme mostrado no exemplo a seguir:The endpoint that processes the error can get the original URL that generated the error, as shown in the following example:

var statusCodeReExecuteFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature != null)
{
    OriginalURL =
        statusCodeReExecuteFeature.OriginalPathBase
        + statusCodeReExecuteFeature.OriginalPath
        + statusCodeReExecuteFeature.OriginalQueryString;
}

Desabilitar páginas de código de statusDisable status code pages

Para desabilitar as páginas de código de status de um método de ação ou controlador MVC, use o atributo [SkipStatusCodePages].To disable status code pages for an MVC controller or action method, use the [SkipStatusCodePages] attribute.

Para desabilitar as páginas de código de status de solicitações específicas em um método manipulador Razor Pages ou em um controlador MVC, use IStatusCodePagesFeature:To disable status code pages for specific requests in a Razor Pages handler method or in an MVC controller, use IStatusCodePagesFeature:

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

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

Código de tratamento de exceçãoException-handling code

Código em páginas de tratamento de exceção pode gerar exceções.Code in exception handling pages can throw exceptions. Geralmente, é uma boa ideia que páginas de erro de produção sejam compostas por conteúdo puramente estático.It's often a good idea for production error pages to consist of purely static content.

Cabeçalhos de respostaResponse headers

Depois que os cabeçalhos de resposta são enviados:Once the headers for a response are sent:

  • O aplicativo já não consegue alterar o código de status da resposta.The app can't change the response's status code.
  • As páginas de exceção ou manipuladores não podem ser executados.Any exception pages or handlers can't run. A resposta deve ser concluída ou a conexão será anulada.The response must be completed or the connection aborted.

Tratamento de exceções do servidorServer exception handling

Além da lógica de tratamento de exceção no aplicativo, a implementação do servidor HTTP pode lidar com algumas exceções.In addition to the exception handling logic in your app, the HTTP server implementation can handle some exceptions. Se o servidor capturar uma exceção antes que os cabeçalhos de resposta sejam enviados, o servidor enviará uma resposta 500 Erro Interno do Servidor sem um corpo de resposta.If the server catches an exception before response headers are sent, the server sends a 500 - Internal Server Error response without a response body. Se o servidor capturar uma exceção depois que os cabeçalhos de resposta forem enviados, o servidor fechará a conexão.If the server catches an exception after response headers are sent, the server closes the connection. As solicitações que não são manipuladas pelo aplicativo são manipuladas pelo servidor.Requests that aren't handled by your app are handled by the server. Qualquer exceção que ocorrer quando o servidor estiver tratando a solicitação será tratada pelo tratamento de exceção do servidor.Any exception that occurs when the server is handling the request is handled by the server's exception handling. As páginas de erro personalizadas do aplicativo, o middleware de tratamento de exceção e os filtros configurados não afetam esse comportamento.The app's custom error pages, exception handling middleware, and filters don't affect this behavior.

Tratamento de exceção na inicializaçãoStartup exception handling

Apenas a camada de hospedagem pode tratar exceções que ocorrem durante a inicialização do aplicativo.Only the hosting layer can handle exceptions that take place during app startup. O host pode ser configurado para capturar erros de inicialização e capturar erros detalhados.The host can be configured to capture startup errors and capture detailed errors.

A camada de hospedagem só poderá mostrar uma página de erro para um erro de inicialização capturado se o erro ocorrer após a associação de endereço do host/porta.The hosting layer can show an error page for a captured startup error only if the error occurs after host address/port binding. Se a associação falhar:If binding fails:

  • A camada de hospedagem registrará uma exceção crítica.The hosting layer logs a critical exception.
  • O processo dotnet falhará.The dotnet process crashes.
  • Nenhuma página de erro é exibida quando o servidor HTTP é Kestrel.No error page is displayed when the HTTP server is Kestrel.

Quando executado no IIS (ou no Serviço de Aplicativo do Azure) ou no IIS Express, um erro 502.5 Falha no Processo será retornado pelo Módulo do ASP.NET Core se o processo não puder ser iniciado.When running on IIS (or Azure App Service) or IIS Express, a 502.5 - Process Failure is returned by the ASP.NET Core Module if the process can't start. Para obter mais informações, consulte Solucionar problemas ASP.NET Core no serviço Azure App e no IIS.For more information, see Solucionar problemas ASP.NET Core no serviço Azure App e no IIS.

Página de erro do banco de dadosDatabase error page

O middleware da página de erro do banco de dados captura as exceções relacionadas ao banco de dados que podem ser resolvidas usando Entity Framework migrações.Database Error Page Middleware captures database-related exceptions that can be resolved by using Entity Framework migrations. Quando estas exceções ocorrem, é gerada uma resposta HTML com detalhes das ações possíveis para resolver o problema.When these exceptions occur, an HTML response with details of possible actions to resolve the issue is generated. Esta página só deve ser habilitada no Ambiente de desenvolvimento.This page should be enabled only in the Development environment. Habilite a página adicionando código a Startup.Configure:Enable the page by adding code to Startup.Configure:

if (env.IsDevelopment())
{
    app.UseDatabaseErrorPage();
}

Filtros de exceçãoException filters

Em aplicativos MVC, os filtros de exceção podem ser configurados globalmente, por controlador ou por ação.In MVC apps, exception filters can be configured globally or on a per-controller or per-action basis. Em aplicativos do Razor Pages, eles podem ser configurados globalmente ou por modelo de página.In Razor Pages apps, they can be configured globally or per page model. Esses filtros tratam qualquer exceção sem tratamento ocorrida durante a execução de uma ação do controlador ou de outro filtro.These filters handle any unhandled exception that occurs during the execution of a controller action or another filter. Para obter mais informações, consulte Filtros no ASP.NET Core.For more information, see Filtros no ASP.NET Core.

Dica

Os filtros de exceção são úteis para interceptar exceções que ocorrem em ações do MVC, mas não são tão flexíveis quanto o middleware de tratamento de exceção.Exception filters are useful for trapping exceptions that occur within MVC actions, but they're not as flexible as the Exception Handling Middleware. É recomendável usar o middleware.We recommend using the middleware. Use filtros somente onde você precisar fazer o tratamento de erro de forma diferente com base na ação de MVC escolhida.Use filters only where you need to perform error handling differently based on which MVC action is chosen.

Erros de estado do modeloModel state errors

Confira informações sobre como lidar com erros de estado de modelo em model binding e Validação de modelos.For information about how to handle model state errors, see Model binding and Model validation.

Recursos adicionaisAdditional resources