87 lines
1.7 KiB
JavaScript
87 lines
1.7 KiB
JavaScript
/**
|
|
* Custom error classes and error handling utilities.
|
|
*/
|
|
|
|
/**
|
|
* Base application error.
|
|
*/
|
|
export class AppError extends Error {
|
|
constructor(message, statusCode = 500, code = 'INTERNAL_ERROR') {
|
|
super(message)
|
|
this.name = this.constructor.name
|
|
this.statusCode = statusCode
|
|
this.code = code
|
|
Error.captureStackTrace(this, this.constructor)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validation error (400).
|
|
*/
|
|
export class ValidationError extends AppError {
|
|
constructor(message, details = null) {
|
|
super(message, 400, 'VALIDATION_ERROR')
|
|
this.details = details
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Not found error (404).
|
|
*/
|
|
export class NotFoundError extends AppError {
|
|
constructor(resource = 'Resource') {
|
|
super(`${resource} not found`, 404, 'NOT_FOUND')
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unauthorized error (401).
|
|
*/
|
|
export class UnauthorizedError extends AppError {
|
|
constructor(message = 'Unauthorized') {
|
|
super(message, 401, 'UNAUTHORIZED')
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Forbidden error (403).
|
|
*/
|
|
export class ForbiddenError extends AppError {
|
|
constructor(message = 'Forbidden') {
|
|
super(message, 403, 'FORBIDDEN')
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Conflict error (409).
|
|
*/
|
|
export class ConflictError extends AppError {
|
|
constructor(message = 'Conflict') {
|
|
super(message, 409, 'CONFLICT')
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Format error response for API.
|
|
* @param {Error} error - Error object
|
|
* @returns {object} Formatted error response
|
|
*/
|
|
export function formatErrorResponse(error) {
|
|
if (error instanceof AppError) {
|
|
return {
|
|
error: {
|
|
code: error.code,
|
|
message: error.message,
|
|
...(error.details && { details: error.details }),
|
|
},
|
|
}
|
|
}
|
|
|
|
return {
|
|
error: {
|
|
code: 'INTERNAL_ERROR',
|
|
message: error?.message || 'Internal server error',
|
|
},
|
|
}
|
|
}
|