Aller au contenu principal

27-5 Gestion des erreurs

Qu'arrive-t-il si l'API retourne un code d'erreur, comme 404 par exemple, dans le cas où on essaie d'accéder à un événement qui n'existe pas?

Il nous faut un moyen de passer à la page (composant), un code d'erreur. Pour le moment, la fonction ObtenirEvenement retourne un DTO, mais n'a aucune façon de communiquer à la vue qu'une erreur s'est produite, outre de retourner null.

Type Tuple

C# propose un type appelé Tuple. Un tuple est une structure de données qui permet de regrouper plusieurs éléments en une seule entité. Il est similaire à un objet, mais avec une syntaxe plus simple et une utilisation plus légère. Les tuples sont utiles pour regrouper des valeurs hétérogènes sans avoir à créer une classe ou une structure spécifique.

Un tuple se crée facilement à l'aide de parenthèses, comme ceci:

(int statusCode, string evenement) monTuple = (404, null);
Console.WriteLine(monTuple.statusCode); // 404
Console.WriteLine(monTuple.evenement); // null

Vous comprenez qu'on pourrait utiliser ce principe pour retourner plus d'une valeur dans une fonction! On peut retourner le code de statut de la requête, en plus de l'événement (ou null dans le cas d'une erreur).

Modifier le type de retour de ObtenirEvenement

On commence par préciser que la fonction retournera un Tuple, un mélange de HttpStatusCode et EvenementDto.

Snowfall.Web.Admin/HttpClients/EvenementHttpClient.cs
public async Task<(HttpStatusCode, EvenementDto?)> ObtenirEvenement(int id)

Modifier la fonction ObtenirEvenement

On peut ensuite modifier la fonction de la façon suivante pour retourner un code de statut HTTP et un événement.

Snowfall.Web.Admin/HttpClients/EvenementHttpClient.cs
public async Task<(HttpStatusCode, EvenementDto?)> ObtenirEvenement(int id)
{
string url = $"{BaseApiUrl}/{id}";
var reponse = await _client.GetAsync(url);
var statusCode = reponse.StatusCode;
EvenementDto? evenement = null;

if (reponse.IsSuccessStatusCode)
{
evenement = await reponse.Content.ReadFromJsonAsync<EvenementDto>();
}

return (statusCode, evenement);
}
info

On utilise plutôt la fonction GetAsync sur le client HttpClient qui retourne la réponse complète.

Ensuite, on extrait le code StatusCode du retour.

Si le code de retour correspond à IsSuccessStatusCode (200), on lit le contenu de la réponse pour le convertir en DTO via ReadFromJsonAsync.

Sinon, la variable evenement restera à null.

Finalement, on retourne le tuple (statusCode, evenement).

Gérer l'erreur dans la page (composant)

Pour recevoir un tuple, la modification est relativement simple:

Snowfall.Web.Admin/Pages/Evenements/Show.razor
@code {
[Parameter]
public int Id { get; set; }

private EvenementDto? _evenementDto;

protected override async Task OnInitializedAsync()
{
(var statusCode, _evenementDto) = await EvenementHttpClient.ObtenirEvenement(Id);
}
}

La portion EvenementDto du retour est assignée à la variable privée evenement et le code pour sa part, assigné à une nouvelle variable statusCode.

Ajouter une variable pour contenir un message d'erreur

Snowfall.Web.Admin/Pages/Evenements/Show.razor
@code {
[Parameter]
public int Id { get; set; }

private string? alertMessage;
private EvenementDto? _evenementDto;

protected override async Task OnInitializedAsync()
{
(var statusCode, _evenementDto) = await EvenementHttpClient.ObtenirEvenement(Id);

if (statusCode == HttpStatusCode.NotFound)
alertMessage = "Désolé, aucun événement n'a été trouvé.";
}
}
info

Dans le cas où il y a une erreur (NotFound), la variable alertMessage du composant se voit assignée un message d'erreur.

Afficher le message d'erreur

On peut finalement afficher le message d'erreur dans le cas où il y aurait une erreur.

Snowfall.Web.Admin/Pages/Evenements/Show.razor
@if (_evenementDto == null)
{
@if (!string.IsNullOrEmpty(alertMessage))
{
<div class="alert alert-danger">@alertMessage</div>
}
else
{
<p>Chargement...</p>
}
}
else
{

<!-- ... -->

Vous aurez un résultat similaire à celui-ci si vous tentez d'accéder à un identifiant d'événement qui n'existe pas:

http://localhost:4200

Imgur