Gérer les erreurs dans ASP.NET CoreHandle errors in ASP.NET Core

Par Tom Dykstra, Luke Latham et Steve SmithBy Tom Dykstra, Luke Latham, and Steve Smith

Cet article décrit les approches courantes de gestion des erreurs dans ASP.NET Core Web Apps.This article covers common approaches to handling errors in ASP.NET Core web apps. Consultez Gérer les erreurs dans les API Web ASP.NET Core pour les API Web.See Gérer les erreurs dans les API Web ASP.NET Core for web APIs.

Affichez ou téléchargez l’exemple de code.View or download sample code. (Comment télécharger.) L’article contient des instructions sur la façon de définir des directives de préprocesseur (#if, #endif, #define) dans l’exemple d’application pour activer différents scénarios.(How to download.) The article includes instructions about how to set preprocessor directives (#if, #endif, #define) in the sample app to enable different scenarios.

Page d’exceptions du développeurDeveloper Exception Page

La Page d’exceptions du développeur affiche des informations détaillées sur les exceptions des demandes.The Developer Exception Page displays detailed information about request exceptions. Elle est mise à disposition par le package Microsoft.AspNetCore.Diagnostics, qui se trouve dans le métapackage Microsoft.AspNetCore.App.The page is made available by the Microsoft.AspNetCore.Diagnostics package, which is in the Microsoft.AspNetCore.App metapackage. Ajoutez du code à la méthode Startup.Configure pour activer la page lorsque l’application s’exécute dans l’environnement de développement :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();
}

Placez l’appel à UseDeveloperExceptionPage avant tous les middlewares dont vous souhaitez intercepter les exceptions.Place the call to UseDeveloperExceptionPage before any middleware that you want to catch exceptions.

Avertissement

Activez la page d’exception de développeur uniquement quand l’application est en cours d’exécution dans l’environnement de développement.Enable the Developer Exception Page only when the app is running in the Development environment. Il n’est pas souhaitable de partager publiquement des informations détaillées sur les exceptions quand l’application s’exécute en production.You don't want to share detailed exception information publicly when the app runs in production. Pour plus d’informations sur la configuration des environnements, consultez Utiliser plusieurs environnements dans ASP.NET Core.For more information on configuring environments, see Utiliser plusieurs environnements dans ASP.NET Core.

Cette page inclut les informations suivantes sur l’exception et la demande :The page includes the following information about the exception and the request:

  • Trace de pileStack trace
  • Paramètres de la chaîne de requête (le cas échéant)Query string parameters (if any)
  • Cookies (le cas échéant)Cookies (if any)
  • En-têtesHeaders

Pour afficher la Page d’exceptions du développeur dans l’exemple d’application, utilisez la directive de préprocesseur DevEnvironment et sélectionnez Déclencher une exception sur la page d’accueil.To see the Developer Exception Page in the sample app, use the DevEnvironment preprocessor directive and select Trigger an exception on the home page.

Page Gestionnaire d’exceptionsException handler page

Pour configurer une page de gestion des erreurs personnalisée en fonction de l’environnement de production, utilisez le middleware de gestion des exceptions.To configure a custom error handling page for the Production environment, use the Exception Handling Middleware. Le middleware :The middleware:

  • Intercepte et consigne les exceptions.Catches and logs exceptions.
  • Réexécute la requête dans un autre pipeline pour la page ou le contrôleur indiqué(e).Re-executes the request in an alternate pipeline for the page or controller indicated. La demande n’est pas réexécutée si la réponse a démarré.The request isn't re-executed if the response has started.

Dans l’exemple suivant, UseExceptionHandler ajoute le middleware de gestion des exceptions dans des environnements autres que les environnements de développement :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();
}

Le modèle d’application Razor Pages fournit une page d’erreur ( .cshtml) et une classe PageModel (ErrorModel) dans le dossier Pages.The Razor Pages app template provides an Error page (.cshtml) and PageModel class (ErrorModel) in the Pages folder. Pour une application MVC, le modèle de projet comprend une méthode d’action d’erreur et un affichage correspondant.For an MVC app, the project template includes an Error action method and an Error view. Voici la méthode d’action :Here's the action method:

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

Ne décorez pas la méthode d’action du gestionnaire d’erreurs avec des attributs de méthode HTTP, tels que HttpGet.Don't decorate the error handler action method with HTTP method attributes, such as HttpGet. Les verbes explicites empêchent certaines demandes d’atteindre la méthode.Explicit verbs prevent some requests from reaching the method. Autorisez l’accès anonyme à la méthode afin que les utilisateurs non authentifiés puissent recevoir la vue des erreurs.Allow anonymous access to the method so that unauthenticated users are able to receive the error view.

Accéder à l'exceptionAccess the exception

Utilisez IExceptionHandlerPathFeature pour accéder à l’exception et au chemin de la demande d’origine dans une page ou un contrôleur de gestionnaire d’erreurs :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";
}

Avertissement

Ne communiquez pas d’informations sensibles sur les erreurs aux clients.Do not serve sensitive error information to clients. Cela représenterait un risque de sécurité.Serving errors is a security risk.

Pour afficher la page de gestion des exceptions dans l’exemple d’application, utilisez les directive de préprocesseur ProdEnvironment et ErrorHandlerPage et sélectionnez Déclencher une exception sur la page d’accueil.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.

Expression lambda Gestionnaire d’exceptionsException handler lambda

En dehors d’une page de gestionnaire d’exceptions personnalisée, il est possible de fournir une expression lambda à UseExceptionHandler,An alternative to a custom exception handler page is to provide a lambda to UseExceptionHandler. ce qui permet d’accéder à l’erreur avant de retourner la réponse.Using a lambda allows access to the error before returning the response.

Voici un exemple d’utilisation d’une expression lambda pour la gestion des exceptions :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();
}

Avertissement

Ne distribuez pas d’informations sensibles sur les erreurs de IExceptionHandlerFeature ou de IExceptionHandlerPathFeature aux clients.Do not serve sensitive error information from IExceptionHandlerFeature or IExceptionHandlerPathFeature to clients. Cela représenterait un risque de sécurité.Serving errors is a security risk.

Pour afficher le résultat de l’expression lambda de gestion des exceptions dans l’exemple d’application, utilisez les directive de préprocesseur ProdEnvironment et ErrorHandlerLambda et sélectionnez Déclencher une exception sur la page d’accueil.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

Par défaut, une application ASP.NET Core ne fournit pas une page de codes d’état pour les codes d’état HTTP, comme 404 - Introuvable.By default, an ASP.NET Core app doesn't provide a status code page for HTTP status codes, such as 404 - Not Found. L’application retourne un code d’état et un corps de réponse vide.The app returns a status code and an empty response body. Pour fournir des pages de codes d’état, utilisez le middleware Pages de codes d’état.To provide status code pages, use Status Code Pages middleware.

Le middleware est mis à disposition par le package Microsoft.AspNetCore.Diagnostics, qui se trouve dans le métapackage Microsoft.AspNetCore.App.The middleware is made available by the Microsoft.AspNetCore.Diagnostics package, which is in the Microsoft.AspNetCore.App metapackage.

Pour activer les gestionnaires exclusivement textuels par défaut des codes d’état d’erreur courants, appelez UseStatusCodePages dans la méthode Startup.Configure :To enable default text-only handlers for common error status codes, call UseStatusCodePages in the Startup.Configure method:

app.UseStatusCodePages();

Appelez UseStatusCodePages avant les middlewares de gestion des demandes (par exemple, le middleware de fichiers statiques et le middleware MVC).Call UseStatusCodePages before request handling middleware (for example, Static File Middleware and MVC Middleware).

Voici un exemple du texte affiché par les gestionnaires par défaut :Here's an example of text displayed by the default handlers:

Status Code: 404; Not Found

Pour voir l’un des formats de pages de codes d’état dans l’exemple d’application, utilisez une des directives de préprocesseur qui commencent par StatusCodePages, puis sélectionnez Déclencher une erreur 404 sur la page d’accueil.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 avec chaîne de formatUseStatusCodePages with format string

Pour personnaliser le texte et le type de contenu de la réponse, utilisez la surcharge de UseStatusCodePages qui prend un type de contenu et une chaîne de format :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 avec expression lambdaUseStatusCodePages with lambda

Pour spécifier un code personnalisé de gestion des erreurs et d’écriture de la réponse, utilisez la surcharge de UseStatusCodePages qui prend une expression 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

La méthode d’extension UseStatusCodePagesWithRedirects :The UseStatusCodePagesWithRedirects extension method:

  • Envoie un code d’état 302 - Trouvé au client.Sends a 302 - Found status code to the client.
  • Redirige le client à l’emplacement fourni dans le modèle d’URL.Redirects the client to the location provided in the URL template.
app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}");

Le modèle d’URL peut comporter un espace réservé {0} pour le code d’état, comme dans l’exemple.The URL template can include a {0} placeholder for the status code, as shown in the example. S’il commence par un tilde (~), celui-ci est remplacé par le PathBase de l’application.If the URL template starts with a tilde (~), the tilde is replaced by the app's PathBase. Si vous pointez vers un point de terminaison dans l’application, créez une vue MVC ou une page Razor pour le point de terminaison.If you point to an endpoint within the app, create an MVC view or Razor page for the endpoint. Pour consulter un exemple Razor Pages, voir Pages/StatusCode.cshtml dans l’exemple d’application.For a Razor Pages example, see Pages/StatusCode.cshtml in the sample app.

Cette méthode est généralement utilisée lorsque l’application :This method is commonly used when the app:

  • Doit rediriger le client vers un autre point de terminaison, généralement dans les cas où une autre application traite l’erreur.Should redirect the client to a different endpoint, usually in cases where a different app processes the error. Pour les applications web, la barre d’adresses du navigateur client reflète le point de terminaison redirigé.For web apps, the client's browser address bar reflects the redirected endpoint.
  • Ne doit pas conserver ni retourner le code d’état d’origine avec la réponse de redirection initiale.Shouldn't preserve and return the original status code with the initial redirect response.

UseStatusCodePagesWithReExecuteUseStatusCodePagesWithReExecute

La méthode d’extension UseStatusCodePagesWithReExecute :The UseStatusCodePagesWithReExecute extension method:

  • Retourne le code d’état d’origine au client.Returns the original status code to the client.
  • Génère le corps de la réponse en réexécutant le pipeline de requête avec un autre chemin.Generates the response body by re-executing the request pipeline using an alternate path.
app.UseStatusCodePagesWithReExecute("/StatusCode","?code={0}");

Si vous pointez vers un point de terminaison dans l’application, créez une vue MVC ou une page Razor pour le point de terminaison.If you point to an endpoint within the app, create an MVC view or Razor page for the endpoint. Pour consulter un exemple Razor Pages, voir Pages/StatusCode.cshtml dans l’exemple d’application.For a Razor Pages example, see Pages/StatusCode.cshtml in the sample app.

Cette méthode est généralement utilisée lorsque l’application doit :This method is commonly used when the app should:

  • Traiter la demande sans la rediriger vers un autre point de terminaison.Process the request without redirecting to a different endpoint. Pour les applications web, la barre d’adresses du navigateur client reflète le point de terminaison demandé à l’origine.For web apps, the client's browser address bar reflects the originally requested endpoint.
  • Conserver et retourner le code d’état d’origine avec la réponse.Preserve and return the original status code with the response.

Les modèles d’URL et de chaîne de requête peuvent comporter un espace réservé ({0}) pour le code d’état.The URL and query string templates may include a placeholder ({0}) for the status code. Le modèle d’URL doit commencer par une barre oblique (/).The URL template must start with a slash (/). Si vous utilisez un espace réservé dans le chemin, vérifiez que le point de terminaison (page ou contrôleur) peut traiter le segment de chemin.When using a placeholder in the path, confirm that the endpoint (page or controller) can process the path segment. Par exemple, une Razor Page pour les erreurs doit accepter la valeur du segment de chemin d’accès facultatif avec la directive @page :For example, a Razor Page for errors should accept the optional path segment value with the @page directive:

@page "{code?}"

Le point de terminaison qui traite l’erreur peut récupérer l’URL d’origine qui a généré l’erreur, comme dans l’exemple suivant :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;
}

Désactiver les pages de codes d’étatDisable status code pages

Pour désactiver les pages de codes d’état d’un contrôleur MVC ou d’une méthode d’action, utilisez l’attribut [SkipStatusCodePages].To disable status code pages for an MVC controller or action method, use the [SkipStatusCodePages] attribute.

Pour désactiver les pages de codes d’état de requêtes spécifiques dans une méthode de gestionnaire Razor Pages ou dans un contrôleur MVC, utilisez 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;
}

Code de gestion des exceptionsException-handling code

Le code dans les pages de gestion des exceptions peut lever des exceptions.Code in exception handling pages can throw exceptions. Il est souvent judicieux de mettre dans les pages d’erreur de production du contenu purement statique.It's often a good idea for production error pages to consist of purely static content.

En-têtes de réponseResponse headers

Une fois les en-têtes d’une réponse envoyés :Once the headers for a response are sent:

  • L’application ne peut pas modifier le code d’état de la réponse.The app can't change the response's status code.
  • Il est impossible d’exécuter les pages d’exception ou les gestionnaires.Any exception pages or handlers can't run. La réponse doit être accomplie ou la connexion abandonnée.The response must be completed or the connection aborted.

Gestion des exceptions de serveurServer exception handling

En plus de la logique de gestion des exceptions de votre application, l’implémentation de serveur HTTP peut gérer certaines exceptions.In addition to the exception handling logic in your app, the HTTP server implementation can handle some exceptions. Si le serveur intercepte une exception avant que les en-têtes de réponse ne soient envoyés, le serveur envoie une réponse 500 Erreur interne du serveur sans corps de réponse.If the server catches an exception before response headers are sent, the server sends a 500 - Internal Server Error response without a response body. Si le serveur intercepte une exception une fois que les en-têtes de réponse ont été envoyés, il ferme la connexion.If the server catches an exception after response headers are sent, the server closes the connection. Les demandes qui ne sont pas gérées par votre application sont gérées par le serveur.Requests that aren't handled by your app are handled by the server. Toute exception qui se produit tandis que le serveur traite la demande est gérée par le dispositif de gestion des exceptions du serveur.Any exception that occurs when the server is handling the request is handled by the server's exception handling. Ni les pages d’erreur personnalisées de l’application, ni les intergiciels (middleware) de gestion des exceptions, ni les filtres n’ont d’incidence sur ce comportement.The app's custom error pages, exception handling middleware, and filters don't affect this behavior.

Gestion des exceptions de démarrageStartup exception handling

Seule la couche d’hébergement peut gérer les exceptions qui se produisent au démarrage de l’application.Only the hosting layer can handle exceptions that take place during app startup. L’hôte peut être configuré pour capturer les erreurs de démarrage et capturer les erreurs détaillées.The host can be configured to capture startup errors and capture detailed errors.

La couche d’hébergement ne peut afficher la page d’une erreur de démarrage capturée que si celle-ci se produit une fois la liaison établie entre l’adresse d’hôte et le port.The hosting layer can show an error page for a captured startup error only if the error occurs after host address/port binding. Si la liaison échoue :If binding fails:

  • La couche d’hébergement journalise une exception critique.The hosting layer logs a critical exception.
  • Le processus dotnet tombe en panne.The dotnet process crashes.
  • Aucune page d’erreur ne s’affiche si le serveur HTTP est Kestrel.No error page is displayed when the HTTP server is Kestrel.

En cas d’exécution sur IIS (ou Azure App Service) ou IIS Express, une réponse 502.5 - Échec du processus est retournée par le module ASP.NET Core si le processus ne peut pas démarrer.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. Pour plus d'informations, consultez Résoudre les problèmes de ASP.NET Core sur Azure App Service et IIS.For more information, see Résoudre les problèmes de ASP.NET Core sur Azure App Service et IIS.

Page d’erreur de base de donnéesDatabase error page

L’intergiciel (middleware) de page d’erreur de base de données capture des exceptions liées à la base de données qui peuvent être résolues à l’aide de Entity Framework migrations.Database Error Page Middleware captures database-related exceptions that can be resolved by using Entity Framework migrations. Lorsque ces exceptions se produisent, une réponse HTML comportant le détail des actions possibles pour résoudre le problème est générée.When these exceptions occur, an HTML response with details of possible actions to resolve the issue is generated. Cette page ne doit être activée que dans l’environnement de développement.This page should be enabled only in the Development environment. Pour cela, ajoutez du code à Startup.Configure :Enable the page by adding code to Startup.Configure:

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

Filtres d’exceptionsException filters

Dans les applications MVC, vous pouvez configurer les filtres d’exception globalement, contrôleur par contrôleur ou action par action.In MVC apps, exception filters can be configured globally or on a per-controller or per-action basis. Dans les applications Razor Pages, ils peuvent être configurés globalement ou modèle de page par modèle de page.In Razor Pages apps, they can be configured globally or per page model. Ces filtres gèrent les exceptions non prises en charge qui se produisent pendant l’exécution d’une action de contrôleur ou d’un autre filtre.These filters handle any unhandled exception that occurs during the execution of a controller action or another filter. Pour plus d'informations, consultez Filtres dans ASP.NET Core.For more information, see Filtres dans ASP.NET Core.

Conseil

Les filtres d’exceptions sont utiles pour intercepter les exceptions qui se produisent dans les actions MVC, mais n’offrent pas la même souplesse que le middleware de gestion des exceptions.Exception filters are useful for trapping exceptions that occur within MVC actions, but they're not as flexible as the Exception Handling Middleware. Nous vous recommandons d’utiliser le middleware.We recommend using the middleware. N’utilisez des filtres que si vous devez gérer les erreurs différemment en fonction de l’action MVC choisie.Use filters only where you need to perform error handling differently based on which MVC action is chosen.

Erreurs d’état de modèleModel state errors

Pour plus d’informations sur la gestion des erreurs d’état de modèle, voir Liaison de modèles et Validation de modèles.For information about how to handle model state errors, see Model binding and Model validation.

Ressources supplémentairesAdditional resources