Error handling and safe value access are essential for building reliable JavaScript applications.
The try and catch mechanism allows developers to handle runtime errors gracefully without breaking the application flow.
Optional chaining provides a safe way to access deeply nested object properties without causing errors when values are missing.
Nullish coalescing helps define default values only when a variable is null or undefined. Together, these features improve code safety, readability, and robustness.
Error Handling with try/catch
try/catch lets you anticipate errors and handle them gracefully instead of letting your app crash. Introduced in ES3 but refined in modern JS, this pattern is essential for API calls, user inputs, and file operations where things inevitably go wrong.
Basic try/catch Syntax and Flow
The structure wraps risky code in try, catches errors in catch, and optionally runs cleanup in finally.
try {
// Risky code here
const data = JSON.parse(userInput);
} catch (error) {
console.error('Parse failed:', error.message);
} finally {
// Always runs - cleanup code
}Key Components

Practical Error Handling Patterns
Real apps deal with multiple error types. Here's how to handle them systematically:
1. Validate inputs first
function divide(a, b) {
if (typeof b !== 'number' || b === 0) {
throw new Error('Divisor must be non-zero number');
}
return a / b;
}
try {
console.log(divide(10, 'abc')); // Throws custom error
} catch (error) {
alert(`Calculation error: ${error.message}`);
}2. Network request handling
async function fetchUser(id) {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (error) {
console.error('Fetch failed:', error);
return null; // Graceful fallback
}
}
Optional chaining (?.)) safely accesses nested object properties without throwing errors when values are null or undefined.
Before ES2020, developers wrote verbose null checks; now one operator handles it elegantly.
The Problem Optional Chaining Solves
Consider this common crash scenario
// ❌ Crashes if user or address is undefined
const city = user.address.city;With optional chaining
// ✅ Returns undefined safely
const city = user?.address?.city;Chaining Variants
1. ?.: Property access (obj?.prop)
2. ?[ ]: Array index (arr?.[0])
3. ?(): Method calls (func?.())
4. ?.[ ]: Dynamic property access
API Response Handling
const apiResponse = {
data: {
user: { name: 'Jane', profile: { avatar: null } }
}
};
// Safe nested access
const avatar = apiResponse?.data?.user?.profile?.avatar;
// Returns: null (no crash)
// Array access
const firstItem = apiResponse?.data?.items?.[0]?.name;
// Returns: undefined if items missingNullish Coalescing (??)
Nullish coalescing (??) provides default values only when a variable is null or undefined—unlike || which triggers on any falsy value (0, '', false). This distinction prevents bugs in real data scenarios.
Nullish vs Logical OR Operator
The Problem with ||:
// ❌ Wrong defaults for falsy-but-valid values
const userCount = 0;
const count = userCount || 10; // Becomes 10 (wrong!)With ??
// ✅ Respects 0, '', false
const count = userCount ?? 10; // Stays 0 (correct!)Combined Patterns (?. + ??)
These operators work beautifully together:
function displayUser(user) {
const name = user?.name ?? 'Anonymous';
const age = user?.age ?? 0;
const isActive = user?.isActive ?? false;
console.log(`${name}, ${age}yo, Active: ${isActive}`);
}
// Works with messy API data:
displayUser({ name: '', age: 0 }); // "Anonymous, 0yo, Active: false"
displayUser({}); // "", 0, false (respects falsy values)Configuration Objects
const config = {
theme: null,
timeout: 0,
debug: false
};
const settings = {
theme: config.theme ?? 'light',
timeout: config.timeout ?? 5000, // Keeps 0!
debug: config.debug ?? true
};Production Best Practices
Combine these features for bulletproof code:
1. Always wrap async operations
async function safeAPIcall(url) {
try {
const data = await fetch(url).then(r => r.json());
return data?.user?.profile ?? null;
} catch (error) {
console.error('API failed:', error);
return null;
}
}2. Default parameter objects:
function createUser({ name, age = 0, email } = {}) {
const safeEmail = email ?? 'no-email@domain.com';
// Safe property access guaranteed
}
We have a sales campaign on our promoted courses and products. You can purchase 1 products at a discounted price up to 15% discount.