**throw** can throw any value, but by convention always throw **Error objects** (or subclasses) so catch blocks get a consistent `.message` and `.stack` trace. Custom Error classes make error handling much more specific and testable.
1Understanding throw Statement
throw can throw any value, but by convention always throw Error objects (or subclasses) so catch blocks get a consistent .message and .stack trace. Custom Error classes make error handling much more specific and testable.
Always throw Error instances, never plain strings or objects. Error objects include stack traces which are invaluable for debugging.
function divide(a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new TypeError('Arguments must be numbers');
}
if (b === 0) {
throw new RangeError('Division by zero is not allowed');
}
return a / b;
}
try {
console.log(divide(10, 2)); // 5
console.log(divide(10, 0)); // throws
} catch (e) {
console.error(`${e.constructor.name}: ${e.message}`);
}2Practical Example
Here is a real-world application of throw Statement showing how it is used in production JavaScript code.
// Custom Error class
class ValidationError extends Error {
constructor(field, message) {
super(message);
this.name = 'ValidationError';
this.field = field;
}
}
function validateEmail(email) {
if (!email.includes('@')) {
throw new ValidationError('email', 'Invalid email format');
}
}
try { validateEmail('notanemail'); }
catch (e) { console.log(e.name, e.field, e.message); }3Best Practices
Follow these guidelines when working with throw Statement:
1. Always throw Error instances (or subclasses)
2. Use specific error types: TypeError, RangeError, custom errors
3. Include meaningful messages with enough context to debug
Tip: Always throw Error instances, never plain strings or objects. Error objects include stack traces which are invaluable for debugging.
function divide(a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new TypeError('Arguments must be numbers');
}
if (b === 0) {
throw new RangeError('Division by zero is not allowed');
}
return a / b;
}
try {
console.log(divide(10, 2)); // 5
console.log(divide(10, 0)); // throws
} catch (e) {
console.error(`${e.constructor.name}: ${e.message}`);
}