Maison > interface Web > js tutoriel > Vous faites une mauvaise gestion des erreurs !

Vous faites une mauvaise gestion des erreurs !

Susan Sarandon
Libérer: 2024-12-06 11:05:12
original
937 Les gens l'ont consulté

You’re Doing Error-Handling Wrong!

Vous faites une mauvaise gestion des erreurs : plaidoyer en faveur de réponses prévisibles et standardisées

Introduction : une position avisée

La gestion des erreurs en JavaScript est un sujet qui suscite des opinions bien arrêtées, et je suis ici pour partager les miennes : l'approche try-catch traditionnelle est maladroite, peu pratique et obsolète. Chez Garmingo, où nous avons créé Garmingo Status, une solution SaaS pour la surveillance de la disponibilité et de l'infrastructure, nous avons abandonné les blocs try-catch. Au lieu de cela, nous avons adopté une approche basée sur TypeScript qui fournit des réponses prévisibles et standardisées pour les opérations asynchrones.

Cet article explique pourquoi nous pensons que ce paradigme change la donne pour la productivité des développeurs et comment il a contribué à simplifier notre base de code. Bien qu'il s'agisse d'une opinion avisée, j'espère qu'elle vous incitera à repenser la façon dont vous gérez les erreurs dans vos propres projets.

Le problème avec try-catch

Soyons réalistes : la gestion des erreurs en JavaScript peut devenir compliquée. Les blocs try-catch traditionnels comportent de nombreux défis :

  1. Verbosité : Encapsuler chaque appel de fonction asynchrone dans un try-catch ajoute un passe-partout inutile. Cela encombre votre code et nuit à la lisibilité.
  2. Objets d'erreur incohérents : les objets d'erreur JavaScript peuvent varier énormément en termes de structure et de contenu. Sans standardisation, gérer ces erreurs revient souvent à jouer à un jeu de devinettes.
  3. L'enfer logique imbriqué : lorsque vous traitez plusieurs opérations qui peuvent échouer, les blocs try-catch imbriqués transforment votre code en un désordre illisible.

Voici un exemple simple mettant en évidence ces problèmes :

try {
  const user = await fetchUser();
  try {
    const account = await fetchAccount(user.id);
    console.log(account);
  } catch (accountError) {
    console.error('Error fetching account:', accountError);
  }
} catch (userError) {
  console.error('Error fetching user:', userError);
}
Copier après la connexion
Copier après la connexion

Le résultat ? Code plus difficile à lire, à déboguer et à maintenir.

Entrez dans le paradigme de réponse typée TypeScript

Chez Garmingo Status, nous avons abandonné le try-catch au profit d'une structure de réponse standardisée pour toutes les opérations asynchrones. Voici comment cela fonctionne :

La Structure

Chaque fonction asynchrone renvoie une promesse avec un type d'union prédéfini :

Promise<
  | { success: false; error: string }
  | { success: true; result: T }
>;
Copier après la connexion

Cette approche garantit que :

  • Si l'opération échoue, le résultat est toujours { success : false, error : string }.
  • Si ça réussit, c'est { succès : vrai, résultat : T }.
  • Si le succès est vrai, il y a un objet résultat et aucun objet erreur et vice versa. Vous ne pouvez même pas utiliser le résultat sur les réponses ayant échoué.

Voici le même exemple ci-dessus, réécrit avec ce modèle :

const userResponse = await fetchUser();

if (!userResponse.success) {
  console.error('Error fetching user:', userResponse.error);
  return;
}

const accountResponse = await fetchAccount(userResponse.result.id);

if (!accountResponse.success) {
  console.error('Error fetching account:', accountResponse.error);
  return;
}

console.log(accountResponse.result);
Copier après la connexion

Comme vous pouvez le constater, cela n'introduit aucune imbrication pour la logique principale de votre application. Il ajoute simplement ces petites vérifications pour la gestion des erreurs, mais le flux principal reste ininterrompu et peut continuer comme si la gestion des erreurs n'était pas nécessaire en premier lieu.

Les avantages d’une gestion des erreurs prévisible et standardisée

1. Prévisibilité

Le plus grand avantage est de savoir exactement à quoi s'attendre. Que l’opération réussisse ou échoue, la structure est cohérente. Cela élimine l'ambiguïté qui accompagne souvent les objets d'erreur.

2. Facilité d'utilisation

Il est révolu le temps des blocs try-catch profondément imbriqués. Avec l'approche typée, vous pouvez gérer les erreurs en ligne sans interrompre le flux de votre code.

3. Lisibilité améliorée

L'approche structurée rend votre code plus propre et plus facile à suivre. Chaque opération définit clairement ce qui se passe dans les scénarios de réussite et d'échec.

4. Sécurité de type améliorée

L'analyse statique de TypeScript garantit que vous n'oubliez jamais de gérer les erreurs. Si vous omettez accidentellement une vérification de réussite, le compilateur TypeScript le signalera.

Une perspective équilibrée

Aucune approche n’est sans inconvénients. Le paradigme de réponse typée nécessite que vous vérifiiez explicitement l’état de réussite de chaque opération, même si vous êtes sûr qu’elle réussira. Cela ajoute une surcharge mineure par rapport à l'approche traditionnelle, où vous pouvez simplement éviter complètement la gestion des erreurs (bien qu'à vos propres risques).

Cependant, cet « inconvénient » est aussi l'un de ses points forts : il oblige à réfléchir de manière critique aux pannes potentielles, ce qui se traduit par un code plus robuste.

Comment nous l'utilisons sur Garmingo Status

Chez Garmingo, cette approche a transformé la façon dont nous construisons des utilitaires et des bibliothèques asynchrones. Chaque appel d'API et requête de base de données adhère à cette structure de réponse standardisée, garantissant ainsi la cohérence dans notre base de code.
En fait, CHAQUE fonction asynchrone unique qui est réutilisée tout au long du projet et qui pourrait échouer utilise cette approche.
Le résultat ? Une expérience de développement plus fluide (et beaucoup plus rapide) et moins de sessions de débogage de fin de soirée.

Par exemple, une fonction de récupération pourrait ressembler à ceci :

try {
  const user = await fetchUser();
  try {
    const account = await fetchAccount(user.id);
    console.log(account);
  } catch (accountError) {
    console.error('Error fetching account:', accountError);
  }
} catch (userError) {
  console.error('Error fetching user:', userError);
}
Copier après la connexion
Copier après la connexion

Cette prévisibilité a changé la donne pour notre équipe, nous permettant de nous concentrer sur la création de fonctionnalités plutôt que de démêler la logique de gestion des erreurs.

Conclusion

Les blocs try-catch traditionnels ont leur place, mais pour le développement JavaScript moderne – en particulier dans les bases de code lourdes en TypeScript – ils posent souvent plus de problèmes qu'ils n'en valent la peine. En adoptant un paradigme de réponse typée, vous gagnez en prévisibilité, en lisibilité et en tranquillité d'esprit.

Chez Garmingo, nous avons pu constater par nous-mêmes comment cette approche simplifie le développement et améliore notre capacité à fournir un produit raffiné comme Garmingo Status. Même si cela ne convient pas à tout le monde, c'est une approche que je crois fermement que davantage de développeurs devraient envisager.

Alors, êtes-vous prêt à repenser la gestion des erreurs ? Faites-moi part de vos impressions !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal