sync-rules
Version:
CLI tool to synchronize AI coding assistant rule files between projects.
98 lines (97 loc) • 3.06 kB
JavaScript
/**
* Custom error class for sync-rules operations with built-in details support.
*/
export class SyncError extends Error {
details;
constructor(message, details = {}, cause) {
super(message, { cause });
this.name = this.constructor.name;
this.details = details;
}
}
/**
* Error thrown when config file is not found.
*/
export class ConfigNotFoundError extends Error {
path;
isDefault;
constructor(path, isDefault = false) {
super(isDefault
? `Default config file not found at ${path}`
: `Config file not found at ${path}`);
this.name = this.constructor.name;
this.path = path;
this.isDefault = isDefault;
}
}
/**
* Error thrown when config file cannot be parsed or is invalid.
*/
export class ConfigParseError extends Error {
path;
originalError;
constructor(path, originalError) {
super(originalError
? `Failed to load config from ${path}: ${originalError.message}`
: `Failed to parse config from ${path}`, { cause: originalError });
this.name = this.constructor.name;
this.path = path;
this.originalError = originalError;
}
}
/**
* Error thrown when a subprocess spawn fails.
*/
export class SpawnError extends Error {
command;
exitCode;
code;
signal;
constructor(command, code, exitCode, signal, cause) {
const message = SpawnError.buildMessage(command, code, exitCode, signal);
super(message, { cause });
this.name = this.constructor.name;
this.command = command;
this.code = code;
this.exitCode = exitCode;
this.signal = signal;
}
/**
* Builds the appropriate error message based on the error conditions.
* Centralizes all spawn error message strings in one place.
*/
static buildMessage(command, code, exitCode, signal) {
// Command not found (ENOENT)
if (code === "ENOENT") {
return `"${command}" not found on PATH or cwd invalid. Install it or verify working directory.`;
}
// Process killed by signal with specific signal name
if (signal) {
return `Process "${command}" killed by signal ${signal}`;
}
// Tool exited with non-zero code
if (exitCode !== undefined && exitCode !== 0) {
return `Tool '${command}' exited with code ${String(exitCode)}`;
}
// Generic failure
return `Failed to launch "${command}"`;
}
}
/**
* Ensures that an unknown caught value is an Error object.
* @param e - The unknown value to ensure is an Error
*/
export function ensureError(e) {
return e instanceof Error ? e : new Error(String(e));
}
/**
* Type guard to safely check if an error is a Node.js ErrnoException
* @param e - The error to check
*/
export function isNodeError(e) {
return (!!e &&
typeof e === "object" &&
"code" in e &&
(typeof e.code === "string" ||
typeof e.code === "number"));
}