How to Use Try Catch in TypeScript
Use try/catch in TypeScript when code may throw runtime errors or reject promises, and the app needs graceful fallback behavior instead of crashing. This is perfect for API calls, JSON parsing, file operations, and risky user input.
What you’ll build or solve
You’ll learn how to use try/catch in TypeScript with synchronous code, async/await flows, and typed error narrowing. You’ll also know how to safely inspect unknown errors.
Learn TypeScript on Mimo
When this approach works best
This approach is the right choice when failures are expected and recoverable.
Common real-world scenarios include:
- API request failures
- JSON parsing
- Local storage reads
- User input parsing
- File access
This is a bad idea when errors should intentionally bubble up to a higher-level boundary instead of being silently swallowed.
Prerequisites
You only need:
- Basic TypeScript syntax
- Familiarity with async/await
- Understanding of runtime errors
Step-by-step instructions
Step 1: Wrap risky code in try
The try block contains code that may fail.
try {
const data = JSON.parse('{"name":"Alex"}');
console.log(data.name);
} catch (error) {
console.error("Invalid JSON");
}
This prevents invalid input from crashing the app.
Step 2: Narrow the error safely
In TypeScript, catch errors are often unknown.
try {
throw new Error("Failed");
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
}
}
This is the safest way to access error properties.
Step 3: Use try/catch with async code
This is the cleanest async error pattern.
async function loadUser(): Promise<void> {
try {
const response = await fetch("/api/user");
const user = await response.json();
console.log(user);
} catch (error) {
console.error("Failed to load user");
}
}
This keeps async flows readable and safe.
Step 4: Use finally for cleanup
Cleanup logic belongs in finally.
try {
console.log("Loading...");
} catch {
console.log("Failed");
} finally {
console.log("Done");
}
This runs whether the operation succeeds or fails.
What to look for:
- Put risky logic inside
try - Handle recoverable failures in
catch - Narrow errors with
instanceof Error - Use
finallyfor cleanup - Great for async workflows
Examples you can copy
JSON parse
try {
JSON.parse(value);
} catch {}
API fetch
try {
await fetch("/api/users");
} catch {}
Error narrowing
if (error instanceof Error)
Common mistakes and how to fix them
Mistake 1: Accessing error.message directly
What the reader might do:
catch (error) {
console.log(error.message);
}
Why it breaks: error may be unknown.
Corrected approach:
Use instanceof Error.
Mistake 2: Swallowing errors silently
What the reader might do:
catch {}
Why it breaks: debugging becomes much harder.
Corrected approach:
Log, recover, or rethrow intentionally.
Mistake 3: Using try/catch around non-throwing async chains
What the reader might do:
Wrap promise chains without await.
Why it breaks: rejected promises may bypass the catch block.
Corrected approach:
Use await or .catch().
Troubleshooting
If error properties fail, narrow the error type.
If async failures escape, make sure the promise is awaited.
If bugs disappear silently, stop using empty catches.
If cleanup must always run, move it into finally.
Quick recap
- Use
tryfor risky code - Handle failures in
catch - Narrow errors safely
- Use
finallyfor cleanup - Await promises inside
try
Join 35M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot