Gestion des Erreurs

Les erreurs lancées sont une bonne chose! Elles signifient que le runtime a réussi à identifier quand quelque chose dans votre programme a mal tourné et qu'il vous informe en arrêtant la fonction exécution sur la pile actuelle, tuant le processus (dans Node), et vous notifiant dans la console avec une trace de pile.

Utiliser toujours "Error" pour lancer ou rejeter une erreur

JavaScript, ainsi que TypeScript, vous permet de throw ou "lancer" n'importe quel objet. Une promesse peut également être rejetée avec n'importe quel objet de motif. Il est conseillé d'utiliser la syntaxe throw avec un typeError. C'est parce que votre erreur peut être interceptée dans un code de niveau supérieur avec une syntaxe catch. Il serait très déroutant d’y attraper un message de chaîne et débogage plus douloureux. Pour la même raison, vous devez rejeter les promesses avec des types Error.

Mal:

function calculateTotal(items: Item[]): number {
  throw 'Not implemented.';
}

function get(): Promise<Item[]> {
  return Promise.reject('Not implemented.');
}

Bien:

function calculateTotal(items: Item[]): number {
  throw new Error('Not implemented.');
}

function get(): Promise<Item[]> {
  return Promise.reject(new Error('Not implemented.'));
}

// or equivalent to:

async function get(): Promise<Item[]> {
  throw new Error('Not implemented.');
}

L'avantage de l'utilisation des types Error est qu'il est supporté par la syntaxetry/catch/finally et implicitement toutes les erreurs ont l'attribut stack qui est très puissante pour le débogage. Il existe également d'autres alternatives, pour ne pas utiliser la syntaxe throw et renvoyer à la place toujours des objets d'erreur personnalisés. TypeScript rend cela encore plus facile. Prenons l'exemple suivant:

type Result<R> = { isError: false, value: R };
type Failure<E> = { isError: true, error: E };
type Failable<R, E> = Result<R> | Failure<E>;

function calculateTotal(items: Item[]): Failable<number, 'empty'> {
  if (items.length === 0) {
    return { isError: true, error: 'empty' };
  }

  // ...
  return { isError: false, value: 42 };
}

Pour l'explication détaillée de cette idée, reportez-vous à la publication d'origine.

Ne pas ignorer pas les erreurs capturées

Ne rien faire avec une erreur détectée ne vous donne pas la possibilité de corriger ou de réagir à cette erreur. L'enregistrement de l'erreur sur la console (console.log) n'est pas beaucoup mieux car il arrive souvent qu'elle se perde dans un océan de choses imprimées sur la console. Si vous enveloppez un morceau de code dans un try/catch cela signifie que vous pensez qu'une erreur peut s'y produire et que vous devez donc avoir un plan, ou créer un chemin de code, pour quand il se produit.

Mal:

try {
  functionThatMightThrow();
} catch (error) {
  console.log(error);
}

// or even worse

try {
  functionThatMightThrow();
} catch (error) {
  // ignore error
}

Bien:

import { logger } from './logging'

try {
  functionThatMightThrow();
} catch (error) {
  logger.log(error);
}

Ne pas ignorer pas les promesses rejetées

Pour la même raison, vous ne devez pas ignorer les erreurs interceptées de try/catch.

Mal:

getUser()
  .then((user: User) => {
    return sendEmail(user.email, 'Welcome!');
  })
  .catch((error) => {
    console.log(error);
  });

Bien:

import { logger } from './logging'

getUser()
  .then((user: User) => {
    return sendEmail(user.email, 'Welcome!');
  })
  .catch((error) => {
    logger.log(error);
  });

// or using the async/await syntax:

try {
  const user = await getUser();
  await sendEmail(user.email, 'Welcome!');
} catch (error) {
  logger.log(error);
}

results matching ""

    No results matching ""