Crash Courses · Masters
Error Handling & Defensive Patterns
Write code that fails gracefully — catching, surfacing, and recovering from errors correctly.
11 min read+175 XP on completionCert: JavaScript Crash Course
Tap any word in the text below to start reading from there.
Error Handling & Defensive Patterns
Production code fails. Networks drop, APIs return unexpected shapes, users provide bad input. Code that cannot handle failure is not production-ready.
try / catch / finally
async function fetchUser(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('fetchUser failed:', err.message)
throw err // re-throw unless you can handle it here
} finally {
setLoading(false) // always runs
}
}Custom Error Classes
class ApiError extends Error {
constructor(message, status) {
super(message)
this.name = 'ApiError'
this.status = status
}
}
class ValidationError extends Error {
constructor(field, message) {
super(message)
this.name = 'ValidationError'
this.field = field
}
}
try {
await api.getUser(id)
} catch (err) {
if (err instanceof ApiError && err.status === 404) return null
if (err instanceof ValidationError) {
showFieldError(err.field, err.message)
return
}
throw err // unexpected — re-throw
}Guard Clauses
// BAD — nested
function processOrder(order) {
if (order) {
if (order.items.length > 0) {
if (order.total > 0) { /* logic buried */ }
}
}
}
// GOOD — guard clauses
function processOrder(order) {
if (!order) throw new ValidationError('order', 'Order is required')
if (order.items.length === 0) throw new ValidationError('items', 'Cart is empty')
if (order.total <= 0) throw new ValidationError('total', 'Invalid total')
return chargeAndFulfill(order)
}Go-Style Error Tuples
async function safeGet(url) {
try {
const data = await api.get(url)
return [data, null]
} catch (err) {
return [null, err]
}
}
const [user, err] = await safeGet('/api/user')
if (err) { handleError(err); return }
// user guaranteed defined hereReading progress
0% read
In this module
try / catch / finally
Custom Error Class
Guard Clause
Re-throw
0%