javascript
examples
examples.js⚡javascript
/**
* 4.7 Error Types and Custom Errors - Examples
*/
// ============================================
// BUILT-IN ERROR TYPES
// ============================================
console.log('=== Built-in Error Types ===');
// Error
try {
throw new Error('Generic error message');
} catch (e) {
console.log('Error:', e.name, '-', e.message);
}
// TypeError
try {
const x = null;
x.property;
} catch (e) {
console.log('TypeError:', e.message);
}
// ReferenceError
try {
console.log(undefinedVariable);
} catch (e) {
console.log('ReferenceError:', e.message);
}
// RangeError
try {
const arr = new Array(-1);
} catch (e) {
console.log('RangeError:', e.message);
}
// SyntaxError (via eval or JSON.parse)
try {
JSON.parse('{invalid json}');
} catch (e) {
console.log('SyntaxError:', e.message);
}
// URIError
try {
decodeURIComponent('%');
} catch (e) {
console.log('URIError:', e.message);
}
// ============================================
// ERROR OBJECT PROPERTIES
// ============================================
console.log('\n=== Error Properties ===');
try {
throw new Error('Test error');
} catch (error) {
console.log('Name:', error.name);
console.log('Message:', error.message);
console.log('Stack:', error.stack.split('\n')[0]);
}
// ============================================
// AGGREGATE ERROR (ES2021)
// ============================================
console.log('\n=== AggregateError ===');
try {
throw new AggregateError(
[
new Error('First error'),
new TypeError('Second error'),
new RangeError('Third error'),
],
'Multiple errors occurred'
);
} catch (e) {
console.log('Message:', e.message);
console.log('Error count:', e.errors.length);
e.errors.forEach((err, i) => {
console.log(` Error ${i + 1}: ${err.name} - ${err.message}`);
});
}
// ============================================
// BASIC CUSTOM ERROR
// ============================================
console.log('\n=== Basic Custom Error ===');
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = 'ValidationError';
}
}
try {
throw new ValidationError('Email format is invalid');
} catch (e) {
console.log(`${e.name}: ${e.message}`);
console.log('Is ValidationError:', e instanceof ValidationError);
console.log('Is Error:', e instanceof Error);
}
// ============================================
// CUSTOM ERROR WITH PROPERTIES
// ============================================
console.log('\n=== Custom Error with Properties ===');
class HttpError extends Error {
constructor(statusCode, message, body = null) {
super(message);
this.name = 'HttpError';
this.statusCode = statusCode;
this.body = body;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, HttpError);
}
}
get isClientError() {
return this.statusCode >= 400 && this.statusCode < 500;
}
get isServerError() {
return this.statusCode >= 500;
}
toString() {
return `${this.name} [${this.statusCode}]: ${this.message}`;
}
}
try {
throw new HttpError(404, 'Resource not found', { id: 123 });
} catch (e) {
console.log(e.toString());
console.log('Status:', e.statusCode);
console.log('Body:', e.body);
console.log('Is client error:', e.isClientError);
console.log('Is server error:', e.isServerError);
}
// ============================================
// ERROR HIERARCHY
// ============================================
console.log('\n=== Error Hierarchy ===');
// Base application error
class AppError extends Error {
constructor(message, code) {
super(message);
this.name = this.constructor.name;
this.code = code;
this.timestamp = new Date();
}
toJSON() {
return {
name: this.name,
message: this.message,
code: this.code,
timestamp: this.timestamp.toISOString(),
};
}
}
class NotFoundError extends AppError {
constructor(resource, id) {
super(`${resource} with id ${id} not found`, 'NOT_FOUND');
this.resource = resource;
this.resourceId = id;
}
}
class ValidationError2 extends AppError {
constructor(field, message) {
super(message, 'VALIDATION_ERROR');
this.field = field;
}
}
class AuthError extends AppError {
constructor(message = 'Authentication required') {
super(message, 'AUTH_ERROR');
}
}
// Test hierarchy
const errors = [
new NotFoundError('User', 42),
new ValidationError2('email', 'Invalid email format'),
new AuthError(),
];
errors.forEach((err) => {
console.log('\n' + err.name + ':');
console.log(' Message:', err.message);
console.log(' Code:', err.code);
console.log(' JSON:', JSON.stringify(err.toJSON()));
});
// ============================================
// ERROR TYPE CHECKING
// ============================================
console.log('\n=== Error Type Checking ===');
function handleError(error) {
// Using instanceof
if (error instanceof NotFoundError) {
console.log(`Resource ${error.resource} not found`);
} else if (error instanceof ValidationError2) {
console.log(`Validation failed for field: ${error.field}`);
} else if (error instanceof AuthError) {
console.log('Authentication required');
} else if (error instanceof AppError) {
console.log(`App error [${error.code}]: ${error.message}`);
} else {
console.log('Unknown error:', error.message);
}
}
handleError(new NotFoundError('Product', 99));
handleError(new ValidationError2('username', 'Too short'));
handleError(new AuthError('Token expired'));
// ============================================
// ERROR WRAPPING
// ============================================
console.log('\n=== Error Wrapping ===');
class DatabaseError extends Error {
constructor(message, originalError) {
super(message);
this.name = 'DatabaseError';
this.originalError = originalError;
}
}
function simulateDatabaseQuery() {
try {
// Simulate a low-level error
throw new Error('Connection timeout');
} catch (error) {
throw new DatabaseError('Failed to execute query', error);
}
}
try {
simulateDatabaseQuery();
} catch (error) {
console.log('Error:', error.message);
console.log('Original error:', error.originalError.message);
}
// ============================================
// ERROR CAUSE (ES2022)
// ============================================
console.log('\n=== Error Cause (ES2022) ===');
function loadConfig() {
try {
throw new Error('File not found: config.json');
} catch (error) {
throw new Error('Failed to load configuration', { cause: error });
}
}
function initializeApp() {
try {
loadConfig();
} catch (error) {
throw new Error('App initialization failed', { cause: error });
}
}
try {
initializeApp();
} catch (error) {
console.log('Error:', error.message);
console.log('Cause:', error.cause?.message);
console.log('Root cause:', error.cause?.cause?.message);
}
// ============================================
// PRACTICAL: FORM VALIDATION ERRORS
// ============================================
console.log('\n=== Form Validation Example ===');
class FormValidationError extends Error {
constructor(errors) {
super('Form validation failed');
this.name = 'FormValidationError';
this.errors = errors; // { fieldName: [messages] }
}
get fieldErrors() {
return Object.entries(this.errors).map(([field, messages]) => ({
field,
messages,
}));
}
hasErrors(field) {
return field in this.errors;
}
}
function validateUser(data) {
const errors = {};
if (!data.email || !data.email.includes('@')) {
errors.email = ['Invalid email format'];
}
if (!data.password || data.password.length < 8) {
errors.password = ['Password must be at least 8 characters'];
}
if (!data.age || data.age < 18) {
errors.age = ['Must be 18 or older'];
}
if (Object.keys(errors).length > 0) {
throw new FormValidationError(errors);
}
return true;
}
try {
validateUser({ email: 'invalid', password: '123', age: 16 });
} catch (e) {
if (e instanceof FormValidationError) {
console.log('Validation errors:');
e.fieldErrors.forEach(({ field, messages }) => {
console.log(` ${field}: ${messages.join(', ')}`);
});
}
}
// ============================================
// PRACTICAL: API ERROR HANDLING
// ============================================
console.log('\n=== API Error Handling ===');
class APIError extends Error {
constructor(response) {
super(response.message || 'API request failed');
this.name = 'APIError';
this.status = response.status;
this.code = response.code;
this.details = response.details;
}
static fromResponse(status, body) {
return new APIError({
status,
message: body.error?.message || 'Unknown error',
code: body.error?.code,
details: body.error?.details,
});
}
}
async function fetchAPI(url) {
// Simulate API response
const response = {
status: 422,
body: {
error: {
code: 'INVALID_INPUT',
message: 'Invalid request parameters',
details: { field: 'email', reason: 'already exists' },
},
},
};
if (response.status >= 400) {
throw APIError.fromResponse(response.status, response.body);
}
return response.body;
}
(async () => {
try {
await fetchAPI('/api/users');
} catch (e) {
if (e instanceof APIError) {
console.log(`API Error [${e.status}] ${e.code}: ${e.message}`);
console.log('Details:', e.details);
}
}
})();
console.log('\n=== Examples Complete ===');