Chapter 8: Error Handling and Debugging
Chapter 8 of 15
Chapter 8: Error Handling and Debugging
8.1 Try-Catch-Finally
Proper error handling is crucial for robust applications. JavaScript provides try-catch-finally blocks for error management.
try {
// Code that might throw an error
const result = riskyOperation();
console.log(result);
} catch (error) {
// Handle the error
console.error('Error occurred:', error.message);
// Log to error tracking service
logError(error);
} finally {
// Always executes, regardless of success or failure
cleanup();
}
Error Types:
try {
throw new Error('Generic error');
} catch (error) {
if (error instanceof TypeError) {
console.log('Type error');
} else if (error instanceof ReferenceError) {
console.log('Reference error');
} else {
console.log('Other error:', error.message);
}
}
Custom Error Classes:
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = 'ValidationError';
this.field = field;
}
}
class NetworkError extends Error {
constructor(message, statusCode) {
super(message);
this.name = 'NetworkError';
this.statusCode = statusCode;
}
}
function validateUser(user) {
if (!user.email) {
throw new ValidationError('Email is required', 'email');
}
if (!user.name) {
throw new ValidationError('Name is required', 'name');
}
}
8.2 Debugging Techniques
Console Methods:
// Basic logging
console.log('Info message');
console.error('Error message');
console.warn('Warning message');
console.info('Information message');
// Grouping
console.group('User Data');
console.log('Name: John');
console.log('Email: john@example.com');
console.groupEnd();
// Table display
console.table([
{ name: 'John', age: 30 },
{ name: 'Jane', age: 25 }
]);
// Timing
console.time('Operation');
// ... do work ...
console.timeEnd('Operation'); // Logs elapsed time
// Stack trace
console.trace('Function call trace');
Debugger Statement:
function complexFunction() {
const data = fetchData();
debugger; // Execution pauses here in DevTools
const processed = processData(data);
return processed;
}
Breakpoints in DevTools:
- Set breakpoints in Sources panel
- Use conditional breakpoints
- Step through code (F10, F11)
- Watch variables and expressions
- Inspect call stack
8.3 Error Handling Best Practices
// Always handle promises
async function fetchData() {
try {
const response = await fetch('/api/data');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
// Log error
console.error('Fetch error:', error);
// Return fallback or rethrow
throw error;
}
}
// Error boundaries in React
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
logErrorToService(error, errorInfo);
}
render() {
if (this.state.hasError) {
return Something went wrong.
;
}
return this.props.children;
}
}