Quante volte ti sei sentito come gli astronauti dell’Apollo 13 mentre affrontavi eccezioni non gestite nelle applicazioni? Le eccezioni non gestite possono mandare in tilt i sistemi, generare risposte di errore criptiche e rendere i log incomprensibili. Ma non temere, ASP.NET Core fornisce uno strumento potente per gestire queste situazioni: IExceptionHandler.
Per gli sviluppatori impazienti di buttarsi nel codice, il progetto completo è disponibile su GitHub: ExceptionsHandler.NET
Perché IExceptionHandler?
Le eccezioni non gestite possono rovinare l’esperienza degli utenti delle applicazioni e rendere difficile il debug e la risoluzione dei problemi. IExceptionHandler consente di centralizzare la gestione delle eccezioni e fornire risposte coerenti e informative.
Ecco alcuni vantaggi dell’utilizzo di IExceptionHandler:
- Risposte di errore strutturate e facili da comprendere per gli utenti dell’applicazione.
- Logging centralizzato delle eccezioni per semplificare il debug.
- Possibilità di personalizzare la gestione in base al tipo di eccezione.
- Mantenimento di un codice più pulito e leggibile separando la logica di gestione delle eccezioni.
Implementazione
Creazione del Progetto
Per creare il progetto, apri Visual Studio e crea un nuovo progetto di tipo ASP.NET Core Web API
. Assegna un nome al progetto, ad esempio ExceptionsHandler.NET
, e scegli la versione di .NET disponibile. Successivamente, crea una nuova cartella chiamata “Handlers” nella radice del progetto e al suo interno aggiungi un nuovo file denominato GlobalExceptionHandler.cs
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
namespace ExceptionsHandler.NET.Handlers;
public class GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger) : IExceptionHandler
{
public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{
logger.LogError(exception, "Houston, we have a problem! Our code decided to go skydiving without a parachute: {Message}", exception.Message);
var problemDetails = new ProblemDetails
{
Title = "Houston, we have a problem!",
Status = StatusCodes.Status500InternalServerError,
Detail = exception.Message
};
httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken);
return true;
}
}
Il gestore riceve l’eccezione, la registra con un messaggio di errore e restituisce una risposta ProblemDetails strutturata con i dettagli dell’errore.
Configurazione dei servizi
Ora, modifica il file Program.cs
per registrare il gestore di eccezioni, il middleware e abilitare ProblemDetails.
using ExceptionsHandler.NET.Handlers;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
builder.Services.AddProblemDetails();
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.MapControllers();
app.UseExceptionHandler();
app.UseHttpsRedirection();
app.Run();
Creazione API
Crea una nuova cartella chiamata Controllers
nella radice del progetto e al suo interno aggiungi un nuovo file denominato HoustonController.cs
. In questo controller, puoi implementare un’API di esempio per testare il gestore di eccezioni.
using Microsoft.AspNetCore.Mvc;
namespace ExceptionsHandler.NET.Controllers;
[ApiController]
[Route("[controller]/[action]")]
public class HoustonController : ControllerBase
{
[HttpGet]
public IActionResult Error()
{
throw new Exception("Oxygen leak in our API ship!");
}
}
Avvia l’applicazione in modalità debug, apri il browser e vai all’URL https://localhost:5000/swagger, dove vedrai l’interfaccia di Swagger UI con l’elenco degli endpoint disponibili; trova l’endpoint /Houston/Error che genera un’eccezione, clicca su “Try it out” e poi su “Execute”, verificando che la risposta sia una ProblemDetails con i dettagli dell’errore e lo status code 500.
Conclusione
La gestione delle eccezioni è spesso vista come un aspetto tecnico e un po’ sottovalutato nello sviluppo delle applicazioni, ma in realtà è fondamentale per garantire la robustezza e la user experience di un sistema. Implementare un gestore di eccezioni ben strutturato, come quello che abbiamo visto con ASP.NET Core, non solo aiuta a mantenere il codice pulito e gestibile, ma permette anche di rispondere agli errori in modo chiaro e coerente.