JavaScript Error Handling
Throw, catch, and recover from errors in synchronous and asynchronous code
Overview
Errors signal that something unexpected happened, and JavaScript uses throw to raise them and try/catch to handle them. The Error object carries a message and a stack, and you can extend it to create meaningful custom types. Robust handling means catching only what you can recover from and letting the rest propagate.
Syntax / Usage
Wrap risky code in try, handle failures in catch, and run cleanup in finally. Rejected promises are caught with .catch() or with try/catch inside async functions.
function parseConfig(json) {
try {
return JSON.parse(json)
} catch (err) {
console.error('Invalid config:', err.message)
return {}
} finally {
console.log('parse attempt finished')
}
}
// Throwing your own error
function withdraw(balance, amount) {
if (amount > balance) {
throw new RangeError('Insufficient funds')
}
return balance - amount
}
Examples
Define a custom error class to distinguish failure types:
class ValidationError extends Error {
constructor(field, message) {
super(message)
this.name = 'ValidationError'
this.field = field
}
}
function validate(user) {
if (!user.email) throw new ValidationError('email', 'Email required')
}
try {
validate({})
} catch (err) {
if (err instanceof ValidationError) console.log(err.field) // 'email'
else throw err // rethrow unknown errors
}
Handle asynchronous errors with async/await:
async function loadUser(id) {
try {
const res = await fetch(`/api/users/${id}`)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return await res.json()
} catch (err) {
console.error('Failed to load user:', err.message)
return null
}
}
Common Mistakes
- Swallowing errors with an empty
catch {}block, hiding real bugs - Catching everything and continuing as if nothing failed
- Throwing strings or plain objects instead of
Errorinstances (losing the stack) - Forgetting that
throwinside asetTimeoutcallback cannot be caught by an outertry - Not handling promise rejections, causing unhandled rejection warnings
See Also
promises async-await javascript-event-loop