@codervisor/devlog-core
Version:
Core devlog management functionality
151 lines (150 loc) • 4.43 kB
JavaScript
/**
* Standardized error handling for the devlog system
* Provides consistent error types and handling patterns
*/
/**
* Base error class for all devlog-related errors
*/
export class DevlogError extends Error {
timestamp;
context;
constructor(message, context) {
super(message);
this.name = this.constructor.name;
this.timestamp = new Date().toISOString();
this.context = context;
// Maintains proper stack trace for where our error was thrown (only available on V8)
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
}
/**
* Serialize error for logging
*/
toLogObject() {
return {
name: this.name,
message: this.message,
timestamp: this.timestamp,
context: this.context,
stack: this.stack,
};
}
}
/**
* Configuration-related errors
*/
export class DevlogConfigurationError extends DevlogError {
constructor(message, context) {
super(`Configuration Error: ${message}`, context);
}
}
/**
* Storage-related errors
*/
export class DevlogStorageError extends DevlogError {
operation;
constructor(operation, message, context) {
super(`Storage Error (${operation}): ${message}`, context);
this.operation = operation;
}
}
/**
* Validation errors for input data
*/
export class DevlogValidationError extends DevlogError {
field;
constructor(message, field, context) {
super(`Validation Error: ${message}`, context);
this.field = field;
}
}
/**
* Errors related to devlog entries not being found
*/
export class DevlogNotFoundError extends DevlogError {
id;
constructor(id, context) {
super(`Devlog entry '${id}' not found`, context);
this.id = id;
}
}
/**
* API-related errors (GitHub, Jira, etc.)
*/
export class DevlogAPIError extends DevlogError {
service;
statusCode;
responseBody;
constructor(service, message, statusCode, responseBody, context) {
super(`API Error (${service}): ${message}`, context);
this.service = service;
this.statusCode = statusCode;
this.responseBody = responseBody;
}
}
/**
* Network/connectivity errors
*/
export class DevlogNetworkError extends DevlogError {
originalError;
constructor(message, originalError, context) {
super(`Network Error: ${message}`, context);
this.originalError = originalError;
}
}
/**
* Default console logger implementation
*/
export class ConsoleLogger {
error(message, context) {
console.error(`[ERROR] ${message}`, context ? JSON.stringify(context, null, 2) : '');
}
warn(message, context) {
console.warn(`[WARN] ${message}`, context ? JSON.stringify(context, null, 2) : '');
}
info(message, context) {
console.log(`[INFO] ${message}`, context ? JSON.stringify(context, null, 2) : '');
}
debug(message, context) {
console.debug(`[DEBUG] ${message}`, context ? JSON.stringify(context, null, 2) : '');
}
}
/**
* Global logger instance
*/
export const logger = new ConsoleLogger();
/**
* Helper function to handle async operations with proper error logging
*/
export async function handleAsyncOperation(operation, operationName, context) {
try {
return await operation();
}
catch (error) {
const errorContext = {
operation: operationName,
...context,
originalError: error instanceof Error ? error.message : String(error),
};
if (error instanceof DevlogError) {
logger.error(`${operationName} failed`, { ...errorContext, ...error.toLogObject() });
throw error;
}
else {
logger.error(`${operationName} failed with unexpected error`, errorContext);
throw new DevlogError(`${operationName} failed: ${error instanceof Error ? error.message : String(error)}`, errorContext);
}
}
}
/**
* Helper function to wrap operations that might throw and convert to DevlogError
*/
export function wrapError(operation, errorMessage, context) {
try {
return operation();
}
catch (error) {
throw new DevlogError(`${errorMessage}: ${error instanceof Error ? error.message : String(error)}`, { ...context, originalError: error });
}
}