Error Narrowing in Async Code
12345678910111213141516async function fetchUserData(userId: string): Promise<void> { try { const response = await fetch(`/api/users/${userId}`); if (!response.ok) { throw new Error(`Request failed with status: ${response.status}`); } const data = await response.json(); console.log("User data:", data); } catch (error: unknown) { if (error instanceof Error) { console.error("An error occurred:", error.message); } else { console.error("An unexpected error occurred."); } } }
When working with asynchronous code in TypeScript, handling errors correctly is essential for building robust applications. Unlike synchronous code, async functions often deal with errors that can come from a variety of sources, including network failures, invalid responses, and unexpected runtime exceptions. In TypeScript, the type of the value caught in a catch block is always unknown when you use catch (error: unknown), which is a best practice to avoid unsafe assumptions about the error's structure.
Narrowing errors safely is crucial because you cannot guarantee that the caught error will always be an instance of the built-in Error class. For example, libraries or other code might throw strings, numbers, or custom objects. If you try to access properties like message or stack on an unknown value without narrowing, you risk runtime errors.
The recommended approach is to use the instanceof Error type guard inside your catch block. This check ensures that you are only accessing properties like message on objects that are actually instances of Error. If the error is not an Error, you can handle it generically, such as by logging a generic message or rethrowing the value. This pattern helps you avoid unsafe assumptions and keeps your error handling predictable and type-safe.
Avoid casting the error directly to Error or assuming its shape without a guard. Unsafe patterns, such as catch (error) { console.error(error.message); }, can introduce subtle bugs if a non-Error value is thrown. Always prefer explicit narrowing using type guards to keep your code safe and maintainable, especially in asynchronous workflows where the source and type of errors may be unpredictable.
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat
Can you explain more about why TypeScript treats caught errors as unknown?
What are some examples of non-Error values that might be thrown?
How can I handle custom error types in my async functions?
Awesome!
Completion rate improved to 5.88
Error Narrowing in Async Code
Stryg for at vise menuen
12345678910111213141516async function fetchUserData(userId: string): Promise<void> { try { const response = await fetch(`/api/users/${userId}`); if (!response.ok) { throw new Error(`Request failed with status: ${response.status}`); } const data = await response.json(); console.log("User data:", data); } catch (error: unknown) { if (error instanceof Error) { console.error("An error occurred:", error.message); } else { console.error("An unexpected error occurred."); } } }
When working with asynchronous code in TypeScript, handling errors correctly is essential for building robust applications. Unlike synchronous code, async functions often deal with errors that can come from a variety of sources, including network failures, invalid responses, and unexpected runtime exceptions. In TypeScript, the type of the value caught in a catch block is always unknown when you use catch (error: unknown), which is a best practice to avoid unsafe assumptions about the error's structure.
Narrowing errors safely is crucial because you cannot guarantee that the caught error will always be an instance of the built-in Error class. For example, libraries or other code might throw strings, numbers, or custom objects. If you try to access properties like message or stack on an unknown value without narrowing, you risk runtime errors.
The recommended approach is to use the instanceof Error type guard inside your catch block. This check ensures that you are only accessing properties like message on objects that are actually instances of Error. If the error is not an Error, you can handle it generically, such as by logging a generic message or rethrowing the value. This pattern helps you avoid unsafe assumptions and keeps your error handling predictable and type-safe.
Avoid casting the error directly to Error or assuming its shape without a guard. Unsafe patterns, such as catch (error) { console.error(error.message); }, can introduce subtle bugs if a non-Error value is thrown. Always prefer explicit narrowing using type guards to keep your code safe and maintainable, especially in asynchronous workflows where the source and type of errors may be unpredictable.
Tak for dine kommentarer!