Aller au contenu principal

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.

  1. 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.ts
    async 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) {

    }
    }
  2. Pour détecter si l'erreur est de type 406, on doit utiliser la propriété status sur l'objet reponse de l'erreur axios.
src/app/core/services/projet-service.ts
//...

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;
}
info

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!

  1. Créer une classe NotFoundError à l'aide du CLI

    ng g class core/errors/not-found-error
    src/app/core/errors/not-found-error.ts
    export class NotFoundError {
    }
  2. Faisons hériter la classe de Error

    src/app/core/errors/not-found-error.ts
    export class NotFoundError extends Error {
    }
  3. Définissez un constructeur appelant le constructeur parent, ainsi qu'assignant le nom de l'erreur.

    src/app/core/errors/not-found-error.ts
    export class NotFoundError extends Error {
    constructor(message?: string) {
    super(message);
    this.name = 'NotFoundError';
    }
    }
  4. Il est maintenant possible de lancer cette erreur lors d'une requête générant un 406.

    src/app/core/services/projet-service.ts
    async 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

src/app/features/projets/pages/projet-detail.ts
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
}
}
}
}
info

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é.

Imgur

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.

http://localhost:4200

Level Up