Gestire gli errori in modo efficace è fondamentale per creare applicazioni robuste. Con TypeScript puoi sfruttare la digitazione statica e le funzionalità avanzate per scrivere codice più gestibile e affidabile. Questa guida dettagliata ti guiderà attraverso vari suggerimenti e best practice per la gestione degli errori in TypeScript, spiegandoli in modo approfondito.
IL provare…prendere Il costrutto è uno strumento fondamentale per la gestione degli errori. Tuttavia, dovrebbe essere utilizzato con considerazione per mantenere la chiarezza e le prestazioni del codice.
async function fetchData(url: string): Promise<void> {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
}
Qui, gli errori vengono gestiti localmente all’interno della funzione, consentendole di fallire correttamente senza arrestare in modo anomalo l’applicazione.
Le classi di errore personalizzate forniscono una migliore categorizzazione, semplificando la distinzione tra i vari tipi di errore.
Estendendo il built-in Errore class, puoi aggiungere proprietà o metodi personalizzati agli errori. Ciò è particolarmente utile per distinguere tra errori specifici dell’applicazione ed errori di sistema.
class ValidationError extends Error {
constructor(message: string) {
super(message);
this.name = 'ValidationError';
}
}
try {
throw new ValidationError('Invalid input data');
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation Error:', error.message);
} else {
console.error('Unexpected Error:', error);
}
}
Con Errore di convalida, puoi gestire in modo esplicito gli errori relativi all’input non valido, fornendo feedback più mirati.
I tipi di unione consentono di gestire in modo esplicito sia i casi di successo che quelli di fallimento, migliorando la chiarezza e riducendo i controlli di runtime.
I tipi di unione aiutano a garantire che venga tenuto conto di ogni possibile risultato di una funzione. Ciò evita situazioni in cui una funzione fallisce silenziosamente o restituisce risultati imprevisti.
type Result<T> = { success: true; data: T } | { success: false; error: string };
function performTask(): Result<number> {
if (Math.random() > 0.5) {
return { success: true, data: 42 };
} else {
return { success: false, error: 'Task failed' };
}
}
const result = performTask();
if (result.success) {
console.log('Data:', result.data);
} else {
console.error('Error:', result.error);
}
In questo approccio, il Risultato type impone la gestione esplicita sia degli scenari di successo che di errore.
IL Mai type garantisce la gestione di tutti i casi possibili nella logica di gestione degli errori.
Quando si ha a che fare con tipi di unione o casi di scambio, Mai funge da salvaguardia per individuare scenari non gestiti in fase di compilazione.
type AppError = ValidationError | SyntaxError;
function handleAppError(error: AppError): void {
switch (error.name) {
case 'ValidationError':
console.error('Validation error:', error.message);
break;
case 'SyntaxError':
console.error('Syntax error:', error.message);
break;
default:
const exhaustiveCheck: never = error;
throw new Error(`Unhandled error: ${exhaustiveCheck}`);
}
}
IL predefinito case garantisce che nessun tipo di errore venga lasciato non gestito. Se aggiungi un nuovo tipo di errore, TypeScript contrassegnerà questo codice come incompleto, chiedendoti di gestire il nuovo tipo.
La centralizzazione della gestione degli errori riduce la duplicazione del codice e fornisce una strategia unificata per la gestione degli errori dell’applicazione.
La gestione centralizzata degli errori è particolarmente utile in framework come Express o NestJS, dove è possibile definire un middleware o un filtro globale per la gestione degli errori.
import express, { Request, Response, NextFunction } from 'express';
const app = express();
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
console.error('Error:', err.message);
res.status(500).json({ error: err.message });
});
Questo approccio garantisce che tutti gli errori non gestiti vengano rilevati e gestiti in modo coerente.
Tipi di utilità TypeScript come Parziale, Scegliere, E Sola lettura aiutano a definire sottoinsiemi specifici di strutture di errore.
I tipi di utilità consentono di concentrarsi sulle proprietà rilevanti di un oggetto errore, riducendo i valori standard e migliorando la manutenibilità.
type ErrorResponse = Pick<CustomError, 'message' | 'statusCode'>;
function handleErrorResponse(error: ErrorResponse): void {
console.error(`Error (${error.statusCode}): ${error.message}`);
}
Qui, Scegliere garantisce che solo le proprietà necessarie di Errore personalizzato vengono utilizzati nella logica di gestione degli errori.
Gli strumenti di monitoraggio degli errori come Sentry o Rollbar forniscono preziose informazioni sugli errori dell’applicazione, aiutandoti a eseguire il debug e a migliorare l’affidabilità.
Gli strumenti di monitoraggio acquisiscono gli errori di runtime e forniscono report dettagliati, tra cui analisi dello stack, sessioni utente e dettagli sull’ambiente.
import * as Sentry from '@sentry/node';
Sentry.init({ dsn: 'your-dsn' });
try {
// Risky operation
} catch (error) {
Sentry.captureException(error);
console.error('Error captured:', error);
}
Questi strumenti sono particolarmente utili negli ambienti di produzione per rilevare e affrontare i problemi in modo proattivo.
La gestione degli errori è una pietra miliare dell’affidabilità delle applicazioni. Sfruttando le caratteristiche di TypeScript, come la tipizzazione statica, i tipi unione e le classi di errore personalizzate, è possibile costruire sistemi che gestiscono gli errori con grazia e mantengono elevati standard di qualità del codice. L’adozione di queste best practice non solo renderà le applicazioni più robuste, ma migliorerà anche l’esperienza complessiva dello sviluppatore.
Hey, having any query? Our experts are just one click away to respond you.
Contact Us