24-6 Page 404
On ne gère pas les cas où accéder à un composant de page pour une ressource inexistante, par exemple un id
de projet qui n'existe pas, devrait retourner une page 404.
Pour gérer ce cas de figure, il faut détecter l'erreur lors de la requête d'API et faire remonter l'erreur au composant pour qu'il puisse rediriger ou à tout de moins traiter l'erreur de façon adéquate.
Nous allons tenter de détecter l'erreur liée à la page de détail d'un projet
Détecter l'erreur 404 dans le service
La première étape consiste à détecter l'erreur dans le service. En effet, axios soulève une erreur dans le cas d'un problème, mais encore faut-il détecter qu'il s'agit d'une erreur de ressource non trouvée. On se souvient que Supabase retournera le code 406
et non 404
.
- Pour détecter l'erreur, on doit englober dans un
try/catch
la requête à l'API au niveau du service.src/app/core/services/projet-service.tsasync obtenir(id: number): Promise<Projet> {
const url = "/projets";
const config: AxiosRequestConfig = {
params: {
id: `eq.${id}`
},
headers: {
'Accept': 'application/vnd.pgrst.object+json'
}
}
try {
const reponse = await api.get<Projet>(url, config);
return reponse.data;
} catch (error) {
}
} - Pour détecter si l'erreur est de type
406
, on doit utiliser la propriétéstatus
sur l'objetreponse
de l'erreur axios.
//...
try {
const reponse = await api.get<Projet>(url, config);
return reponse.data;
} catch (error) {
if(isAxiosError(error) && error.response?.status === 406) {
// traiter l'erreur
}
throw error;
}
isAxiosError
Permets de déterminer s'il s'agit bien d'une erreur axios et non de toute autre forme d'erreur générique.
throw error
permet de lancer l'erreur normalement dans le cas où l'erreur serait autre qu'une erreur 404.
Lancer une erreur personnalisée
Pour envoyer une erreur personnalisée aux composants utilisant le service, il est possible de créer notre propre classe d'erreur héritant de la classe Error
!
-
Créer une classe
NotFoundError
à l'aide duCLI
ng g class core/errors/not-found-error
src/app/core/errors/not-found-error.tsexport class NotFoundError {
} -
Faisons hériter la classe de
Error
src/app/core/errors/not-found-error.tsexport class NotFoundError extends Error {
} -
Définissez un constructeur appelant le constructeur parent, ainsi qu'assignant le nom de l'erreur.
src/app/core/errors/not-found-error.tsexport class NotFoundError extends Error {
constructor(message?: string) {
super(message);
this.name = 'NotFoundError';
}
} -
Il est maintenant possible de lancer cette erreur lors d'une requête générant un 406.
src/app/core/services/projet-service.tsasync obtenir(id: number): Promise<Projet> {
const url = "/projets";
const config: AxiosRequestConfig = {
params: {
id: `eq.${id}`
},
headers: {
'Accept': 'application/vnd.pgrst.object+json'
}
}
try {
const reponse = await api.get<Projet>(url, config);
return reponse.data;
} catch (error) {
if(isAxiosError(error) && error.response?.status === 406) {
throw new NotFoundError();
}
throw error;
}
}
Attraper l'erreur dans le composant
async chargerProjet() {
if(this.id) {
try {
this.projet = await this.projetService.obtenir(this.id);
} catch (error) {
if(error instanceof NotFoundError) {
// traiter l'erreur comme une erreur 404 et rediriger vers une page de type 404
} else {
// traiter l'erreur générique
}
}
}
}
instanceof
est utilisé pour détecter le type d'objet d'erreur et si ce dernier correspond à l'erreur personnalisée NotFoundError
.
Créer un composant de page 404
et rediriger en cas d'erreur
Vous pouvez maintenant créer une page et rediriger vers cette dernière lorsque l'erreur non-trouvée est rencontrée.
Cette portion est vous est laissé.
Test
Vous pouvez maintenant tenter d'accéder à une adresse de projet qui n'existe pas, par exemple via http://localhost:4200/projets/jenexistepas
et vous serez redirigé vers votre page 404.
