E

Error Handling

Proper error handling in async code ensures robust applications with typed error states.

Code

typescript
1// Custom error classes
2class ApiError extends Error {
3 constructor(
4 message: string,
5 public statusCode: number,
6 public endpoint: string
7 ) {
8 super(message);
9 this.name = "ApiError";
10 }
11}
12
13class ValidationError extends Error {
14 constructor(
15 message: string,
16 public field: string
17 ) {
18 super(message);
19 this.name = "ValidationError";
20 }
21}
22
23// Result type pattern (like Rust's Result)
24type Result<T, E = Error> =
25 | { success: true; data: T }
26 | { success: false; error: E };
27
28async function fetchWithResult<T>(url: string): Promise<Result<T>> {
29 try {
30 // Simulated fetch
31 await new Promise((resolve) => setTimeout(resolve, 100));
32 const data = { message: "Success" } as T;
33 return { success: true, data };
34 } catch (error) {
35 return {
36 success: false,
37 error: error instanceof Error ? error : new Error(String(error))
38 };
39 }
40}
41
42// Using the Result pattern
43async function processData(): Promise<void> {
44 const result = await fetchWithResult<{ message: string }>("/api/data");
45
46 if (result.success) {
47 console.log("Data:", result.data.message);
48 } else {
49 console.error("Failed:", result.error.message);
50 }
51}
52
53// Error type narrowing
54async function handleRequest(): Promise<void> {
55 try {
56 throw new ApiError("Not found", 404, "/users/123");
57 } catch (error) {
58 if (error instanceof ApiError) {
59 console.log(`API Error [${error.statusCode}]: ${error.message}`);
60 console.log(`Endpoint: ${error.endpoint}`);
61 } else if (error instanceof ValidationError) {
62 console.log(`Validation Error on ${error.field}: ${error.message}`);
63 } else if (error instanceof Error) {
64 console.log(`Unknown error: ${error.message}`);
65 } else {
66 console.log("Something went wrong");
67 }
68 }
69}
70
71// Run examples
72processData();
73handleRequest();

Run this example locally

$ npx ts-node async/error-handling.ts