JavaScript Curriculum
Error Handling
mediumThe coffee shop menu fetch fails silently when the API is down. The order form throws a TypeError when querySelector returns null. A structured error handling approach means the user always gets useful feedback, never a blank page.
Error Handling
Errors happen — network failures, null references, invalid input, server outages. The question is not if your code will encounter errors, but how well it handles them when they occur.
JavaScript Error Types
Know your enemy — five error types and how to handle each:
TypeError
Wrong type of thing for this operation
common triggers
Calling a non-function, accessing properties on null/undefined, wrong method for the type
example code
null.name // TypeError: Cannot read properties of null const n = 42 n.toUpperCase() // TypeError: n.toUpperCase is not a function
how to catch
try { ... } catch (err) {
if (err instanceof TypeError) {
// handle it
}
}💡 in practice
The most common runtime error. Usually means you assumed something was an object or function when it was actually null, undefined, or a primitive.
try/catch/finally — Interactive Simulator
See how errors propagate and how each block runs:
Parsing corrupted localStorage data — without try/catch the whole app crashes.
try {
const raw = localStorage.getItem('cart')
const cart = JSON.parse(raw) // raw = '{bad}'
renderCart(cart)
} catch (err) {
console.error('Bad cart data:', err.message)
localStorage.removeItem('cart') // reset
renderCart([]) // safe fallback
}Fetch Error Handling — Status Codes
fetch() has two failure modes — understand both:
async function loadMenu() {
try {
const res = await fetch('/api/menu')
// ↑ rejects ONLY on network failure
if (!res.ok) {
// 404, 500 etc — must check manually
throw new Error(`HTTP ${res.status}: ${res.statusText}`)
}
const data = await res.json()
// ↑ throws SyntaxError if body is not valid JSON
renderCards(data.items)
} catch (err) {
if (err instanceof TypeError) {
showBanner('No internet connection')
} else if (err.message.startsWith('HTTP 4')) {
showBanner('Content not found')
} else if (err.message.startsWith('HTTP 5')) {
showBanner('Server error — try again later')
} else if (err instanceof SyntaxError) {
showBanner('Unexpected response format')
} else {
showBanner('Something went wrong')
}
}
}Your Challenge
Write a fetchWithHandling(url) helper that: awaits fetch, checks res.ok (throws on bad status), parses JSON. In the catch block, uses instanceof to distinguish network errors from HTTP errors. Create a class ValidationError extends Error and throw it from your form validator. Catch it with err instanceof ValidationError.
Challenge
Wrap your loadMenu() function in a full error handler: distinguish TypeError (offline) from HTTP errors, show different UI for each. Create a custom ValidationError class that extends Error, and use instanceof to handle it differently in the catch block.
Error Handling
mediumThe coffee shop menu fetch fails silently when the API is down. The order form throws a TypeError when querySelector returns null. A structured error handling approach means the user always gets useful feedback, never a blank page.
Error Handling
Errors happen — network failures, null references, invalid input, server outages. The question is not if your code will encounter errors, but how well it handles them when they occur.
JavaScript Error Types
Know your enemy — five error types and how to handle each:
TypeError
Wrong type of thing for this operation
common triggers
Calling a non-function, accessing properties on null/undefined, wrong method for the type
example code
null.name // TypeError: Cannot read properties of null const n = 42 n.toUpperCase() // TypeError: n.toUpperCase is not a function
how to catch
try { ... } catch (err) {
if (err instanceof TypeError) {
// handle it
}
}💡 in practice
The most common runtime error. Usually means you assumed something was an object or function when it was actually null, undefined, or a primitive.
try/catch/finally — Interactive Simulator
See how errors propagate and how each block runs:
Parsing corrupted localStorage data — without try/catch the whole app crashes.
try {
const raw = localStorage.getItem('cart')
const cart = JSON.parse(raw) // raw = '{bad}'
renderCart(cart)
} catch (err) {
console.error('Bad cart data:', err.message)
localStorage.removeItem('cart') // reset
renderCart([]) // safe fallback
}Fetch Error Handling — Status Codes
fetch() has two failure modes — understand both:
async function loadMenu() {
try {
const res = await fetch('/api/menu')
// ↑ rejects ONLY on network failure
if (!res.ok) {
// 404, 500 etc — must check manually
throw new Error(`HTTP ${res.status}: ${res.statusText}`)
}
const data = await res.json()
// ↑ throws SyntaxError if body is not valid JSON
renderCards(data.items)
} catch (err) {
if (err instanceof TypeError) {
showBanner('No internet connection')
} else if (err.message.startsWith('HTTP 4')) {
showBanner('Content not found')
} else if (err.message.startsWith('HTTP 5')) {
showBanner('Server error — try again later')
} else if (err instanceof SyntaxError) {
showBanner('Unexpected response format')
} else {
showBanner('Something went wrong')
}
}
}Your Challenge
Write a fetchWithHandling(url) helper that: awaits fetch, checks res.ok (throws on bad status), parses JSON. In the catch block, uses instanceof to distinguish network errors from HTTP errors. Create a class ValidationError extends Error and throw it from your form validator. Catch it with err instanceof ValidationError.
Challenge
Wrap your loadMenu() function in a full error handler: distinguish TypeError (offline) from HTTP errors, show different UI for each. Create a custom ValidationError class that extends Error, and use instanceof to handle it differently in the catch block.