Files
kestrelos/server/utils/errors.js
Madison Grubb b0e8dd7ad9
Some checks failed
ci/woodpecker/pr/pr Pipeline failed
make kestrel a tak server, so that it can send and receive pois as cots data
2026-02-17 10:42:53 -05:00

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',
},
}
}