Skip to content
Plurafy

Debugging and Error Prevention

Techniques for debugging JavaScript applications

Quickly identify and fix bugs in production and development environments. Use debugging tools and strategies effectively.

Debugging is an essential skill. Understanding browser dev tools and debugging patterns helps identify issues quickly.

// Logging
console.log('Basic log');
console.warn('Warning');
console.error('Error');
console.info('Info');
// Grouping
console.group('API Calls');
console.log('GET /users');
console.log('GET /posts');
console.groupEnd();
// Tables
const users = [
{ name: 'John', age: 30 },
{ name: 'Jane', age: 25 }
];
console.table(users);
// Timing
console.time('fetch');
// ... code ...
console.timeEnd('fetch'); // Logs: fetch: 234.5ms
// Assertions
console.assert(value > 0, 'Value must be positive');
// Debugger statement (pauses execution)
function problematicFunction() {
debugger; // Execution pauses here in dev tools
return complexCalculation();
}
// Conditional breakpoints (dev tools only)
// Right-click line number -> Add conditional breakpoint
if (userId === 123) {
debugger; // Only breaks for specific user
}
function outer() {
inner();
}
function inner() {
deepest();
}
function deepest() {
console.trace('Stack trace'); // Shows full call stack
throw new Error('Something went wrong');
}
outer();
/* Stack trace:
at deepest (file.js:10)
at inner (file.js:6)
at outer (file.js:3)
at <anonymous> (file.js:14)
*/
// Try-catch for synchronous errors
try {
JSON.parse('{invalid}');
} catch (e) {
console.error('Parse error:', e.message);
} finally {
console.log('Cleanup'); // Always runs
}
// Distinguish error types
try {
someOperation();
} catch (error) {
if (error instanceof TypeError) {
console.error('Type error:', error);
} else if (error instanceof SyntaxError) {
console.error('Syntax error:', error);
} else {
console.error('Unknown error:', error);
}
}
// Async error handling
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Fetch failed:', error);
// Fallback or recovery
return null;
}
}
// In build config (webpack, vite, etc)
// Enable source maps for production debugging
// .map files allow browser to show original source code
// even when using minified/transpiled code
// In dev tools:
// Sources tab shows original files instead of bundled code
// Common memory leak: Event listeners
const element = document.getElementById('button');
// ❌ Bad: Never removed
element.addEventListener('click', () => console.log('clicked'));
// ✅ Good: Remove when done
const handler = () => console.log('clicked');
element.addEventListener('click', handler);
// Later...
element.removeEventListener('click', handler);
// ❌ Bad: Circular references
class Node {
constructor(value) {
this.value = value;
this.parent = null;
}
}
// ✅ Good: Use WeakMap to avoid memory leaks
const parentMap = new WeakMap();
const node = new Node(5);
parentMap.set(node, parentNode);
// Performance API
performance.mark('operation-start');
// ... code ...
performance.mark('operation-end');
performance.measure(
'operation',
'operation-start',
'operation-end'
);
const measure = performance.getEntriesByName('operation')[0];
console.log(`Operation took ${measure.duration}ms`);
// Entry observations
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(`${entry.name}: ${entry.duration}ms`);
}
});
observer.observe({ entryTypes: ['measure', 'navigation'] });
// Use descriptive error messages
// ❌ throw new Error('Error');
// ✅ throw new Error('Failed to fetch user data from API');
// Include context in logs
// ❌ console.log(error);
// ✅ console.error('Failed to parse config:', { error, file: 'config.json' });
// Use custom error classes
class ValidationError extends Error {
constructor(field, value) {
super(`Validation failed for ${field}: ${value}`);
this.name = 'ValidationError';
this.field = field;
}
}
try {
throw new ValidationError('email', 'invalid');
} catch (error) {
if (error instanceof ValidationError) {
console.log('Field:', error.field);
}
}