Gestion des erreurs en TypeScript : techniques avancées try/catch

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Gestion avancée des erreurs en TypeScript : du try/catch aux solutions typées sécurisées



La gestion des erreurs est un aspect critique du développement en TypeScript. Le try/catch de base s'avère souvent insuffisant pour les applications complexes. Dans cet article, nous examinerons des techniques avancées qui aideront à rendre le code plus fiable, prévisible et typé sécurisé.



1. Problème du try/catch standard : perte des types



Le principal inconvénient du catch classique est que la variable d'erreur a le type unknown (ou any dans les anciennes versions). Cela oblige le développeur à vérifier manuellement le type :



try {  riskyOperation();} catch (error) {  // error: unknown  if (error instanceof Error) {    console.error(error.message);  } else {    console.error('Erreur inconnue', error);  }}


Solution : création d'un utilitaire pour la capture typée des erreurs :



function getErrorMessage(error: unknown): string {  if (error instanceof Error) return error.message;  if (typeof error === 'string') return error;  if (error && typeof error === 'object' && 'message' in error) {    return String((error as { message: unknown }).message);  }  return 'Une erreur inconnue est survenue';}

try { riskyOperation();} catch (error) { console.error(getErrorMessage(error));}


2. Classes d'erreurs personnalisées avec données typées



La création d'une hiérarchie d'erreurs permet d'identifier précisément le problème et de transmettre des données supplémentaires :



// Classe de baseclass AppError extends Error {  constructor(    message: string,    public readonly code: number,    public readonly isOperational: boolean = true  ) {    super(message);    this.name = 'AppError';  }}

// Erreurs spécialiséesclass ValidationError extends AppError { constructor( message: string, public readonly field: string, public readonly invalidValue: unknown ) { super(message, 400); this.name = 'ValidationError'; }}

class NotFoundError extends AppError { constructor(entity: string, id: string) { super(`${entity} avec l'ID ${id} introuvable`, 404, false); this.name = 'NotFoundError'; }}

// Utilisationfunction findUser(id: string): User { if (!validateId(id)) { throw new ValidationError('ID invalide', 'id', id); } const user = db.findUser(id); if (!user) { throw new NotFoundError('Utilisateur', id); } return user;}

try { const user = findUser('123');} catch (error) { if (error instanceof NotFoundError) { // error.code === 404, error.message contient la description console.warn(error.message); } else if (error instanceof ValidationError) { // error.field et error.invalidValue sont disponibles console.error(`Erreur dans le champ ${error.field} : ${error.message}`); } else if (error instanceof AppError) { console.error(`Erreur d'application (code ${error.code}) : ${error.message}`); }}


3. Discriminated Unions pour la gestion des erreurs



Ce modèle permet de traiter les résultats des opérations sans exceptions, en utilisant une union de types avec un discriminant :



// Type de résultat avec discriminanttype Result<T, E = Error> =   | { success: true; data: T }  | { success: false; error: E };

// Fonction retournant un Resultfunction safeDivide(a: number, b: number): Result<number, string> { if (b === 0) { return { success: false, error: 'Division par zéro' }; } return { success: true, data: a / b };}

// Utilisationconst result = safeDivide(10, 0);

if (result.success) { // TypeScript sait que result.data est un number console.log(`Résultat : ${result.data}`);} else { // result.error est une string console.error(`Erreur : ${result.error}`);}

// Exemple plus complexe avec des erreurs personnaliséestype UserResult = Result<

Blogs

Book Recommendations