Les deux approches utilisent le traitement intégré des exceptions intergiciel . Ajoutez ce code avant d'appeler UseMvc
, UseRouting
ou UseEndpoints
. Il traitera les exceptions de tous les middlewares enregistrés après lui.
Solution rapide et facile.
Il suffit d'ajouter ce middleware avant le routage ASP.NET dans vos enregistrements de middleware.
app.UseExceptionHandler(c => c.Run(async context =>
{
var exception = context.Features
.Get<IExceptionHandlerPathFeature>()
.Error;
var response = new { error = exception.Message };
await context.Response.WriteAsJsonAsync(response);
}));
Remarque : ceci est uniquement pour ASP.NET Core 5.0+.
Activez l'injection de dépendances pour la journalisation et/ou d'autres objectifs.
Étape 1. Dans votre startup, enregistrez votre route de traitement des exceptions :
// It should be one of your very first registrations
app.UseExceptionHandler("/error"); // Add this
app.UseEndpoints(endpoints => endpoints.MapControllers());
Étape 2. Créez un contrôleur qui traitera toutes les exceptions et produira une réponse d'erreur :
[AllowAnonymous]
[ApiExplorerSettings(IgnoreApi = true)]
public class ErrorsController : ControllerBase
{
[Route("error")]
public MyErrorResponse Error()
{
var context = HttpContext.Features.Get<IExceptionHandlerFeature>();
var exception = context.Error; // Your exception
var code = 500; // Internal Server Error by default
if (exception is MyNotFoundException) code = 404; // Not Found
else if (exception is MyUnauthException) code = 401; // Unauthorized
else if (exception is MyException) code = 400; // Bad Request
Response.StatusCode = code; // You can use HttpStatusCode enum instead
return new MyErrorResponse(exception); // Your error model
}
}
Quelques notes et observations importantes :
- Vous pouvez injecter vos dépendances dans le constructeur du contrôleur.
-
[ApiExplorerSettings(IgnoreApi = true)]
est nécessaire. Sinon, cela peut casser votre Swashbuckle swagger.
- Encore une fois,
app.UseExceptionHandler("/error");
doit être l'un des meilleurs enregistrements de votre startup. Configure(...)
méthode. Il est probablement plus sûr de le placer au début de la méthode.
- Le chemin dans
app.UseExceptionHandler("/error")
et dans le contrôleur [Route("error")]
doivent être les mêmes, afin de permettre au contrôleur de gérer les exceptions redirigées depuis le middleware de gestion des exceptions.
Voici le lien à la documentation officielle de Microsoft.
Idées de modèles de réponse.
Mettez en œuvre votre propre modèle de réponse et vos propres exceptions. Cet exemple n'est qu'un bon point de départ. Chaque service devra gérer les exceptions à sa manière. Avec l'approche décrite, vous disposez d'une flexibilité et d'un contrôle total sur le traitement des exceptions et le renvoi de la bonne réponse par votre service.
Un exemple de modèle de réponse aux erreurs (pour vous donner quelques idées) :
public class MyErrorResponse
{
public string Type { get; set; }
public string Message { get; set; }
public string StackTrace { get; set; }
public MyErrorResponse(Exception ex)
{
Type = ex.GetType().Name;
Message = ex.Message;
StackTrace = ex.ToString();
}
}
Pour des services plus simples, vous pouvez mettre en œuvre une exception de code d'état http qui ressemblerait à ceci :
public class HttpStatusException : Exception
{
public HttpStatusCode Status { get; private set; }
public HttpStatusException(HttpStatusCode status, string msg) : base(msg)
{
Status = status;
}
}
On peut le lancer de n'importe où de cette façon :
throw new HttpStatusCodeException(HttpStatusCode.NotFound, "User not found");
Votre code de manipulation pourrait alors être simplifié comme suit :
if (exception is HttpStatusException httpException)
{
code = (int) httpException.Status;
}
HttpContext.Features.Get<IExceptionHandlerFeature>()
WAT ?
Les développeurs d'ASP.NET Core ont adopté le concept d'intergiciels où différents aspects de la fonctionnalité tels que Auth, MVC, Swagger, etc. sont séparés et exécutés séquentiellement dans le pipeline de traitement des demandes. Chaque intergiciel a accès au contexte de la demande et peut écrire dans la réponse si nécessaire. Retirer la gestion des exceptions de MVC est logique s'il est important de traiter les erreurs provenant d'intergiciels non-MVC de la même manière que les exceptions MVC, ce qui est très courant dans les applications réelles. Ainsi, comme le middleware de gestion des exceptions intégré ne fait pas partie de MVC, MVC lui-même n'en sait rien et vice versa, le middleware de gestion des exceptions ne sait pas vraiment d'où vient l'exception, à part bien sûr qu'il sait qu'elle s'est produite quelque part dans le tuyau d'exécution de la requête. Mais les deux peuvent avoir besoin d'être "connectés" l'un à l'autre. Ainsi, lorsqu'une exception n'est détectée nulle part, l'intergiciel de gestion des exceptions la détecte et ré-exécute le pipeline pour une route enregistrée dans celui-ci. C'est ainsi que l'on peut "passer" le traitement des exceptions à MVC avec une méthode cohérente. négociation de contenu ou un autre intergiciel si vous le souhaitez. L'exception elle-même est extraite du contexte commun du middleware. Cela a l'air bizarre, mais cela fait l'affaire :).
6 votes
Avez-vous essayé
UseExceptionHandler
intergiciel ?