@xec-sh/core
Version:
Universal shell execution engine
132 lines • 4.49 kB
JavaScript
export class ExecutionError extends Error {
constructor(message, code, details) {
super(message);
this.code = code;
this.details = details;
this.name = 'ExecutionError';
Error.captureStackTrace(this, this.constructor);
}
}
export class CommandError extends ExecutionError {
constructor(command, exitCode, signal, stdout, stderr, duration) {
const sanitizedCommand = sanitizeCommandForError(command);
super(`Command failed with exit code ${exitCode}: ${sanitizedCommand}`, 'COMMAND_FAILED', {
exitCode,
signal,
stdout,
stderr,
duration
});
this.command = command;
this.exitCode = exitCode;
this.signal = signal;
this.stdout = stdout;
this.stderr = stderr;
this.duration = duration;
this.name = 'CommandError';
}
}
export function sanitizeCommandForError(command) {
if (process.env['NODE_ENV'] === 'test' || process.env['JEST_WORKER_ID'] !== undefined) {
return command;
}
if (process.env['XEC_SANITIZE_COMMANDS'] !== 'true') {
return command;
}
const parts = command.trim().split(/\s+/);
if (parts.length === 0)
return command;
const baseCommand = parts[0];
if (!baseCommand)
return command;
const sensitiveCommands = ['cat', 'ls', 'rm', 'cp', 'mv', 'chmod', 'chown', 'find', 'grep'];
const commandName = baseCommand.split('/').pop() || baseCommand;
if (sensitiveCommands.includes(commandName) && parts.length > 1) {
return `${commandName} [arguments hidden]`;
}
if (parts.length > 3) {
return `${baseCommand} ... (${parts.length - 1} arguments)`;
}
return command;
}
export class ConnectionError extends ExecutionError {
constructor(host, originalError) {
super(`Failed to connect to ${host}: ${originalError.message}`, 'CONNECTION_FAILED', {
host,
originalError: originalError.message
});
this.host = host;
this.originalError = originalError;
this.name = 'ConnectionError';
}
}
export class TimeoutError extends ExecutionError {
constructor(command, timeout) {
super(`Command timed out after ${timeout}ms: ${command}`, 'TIMEOUT', {
command,
timeout
});
this.command = command;
this.timeout = timeout;
this.name = 'TimeoutError';
}
}
export class DockerError extends ExecutionError {
constructor(container, operation, originalError) {
super(`Docker operation '${operation}' failed for container ${container}: ${originalError.message}`, 'DOCKER_ERROR', {
container,
operation,
originalError: originalError.message
});
this.container = container;
this.operation = operation;
this.originalError = originalError;
this.name = 'DockerError';
}
}
export class AdapterError extends ExecutionError {
constructor(adapter, operation, originalError) {
let message;
if (originalError) {
const err = originalError;
if (err.code === 'ENOENT' && err.syscall === 'spawn') {
if (err.message.includes('No such file or directory')) {
message = err.message;
}
else {
message = `spawn ENOENT: No such file or directory`;
}
}
else {
message = `Adapter '${adapter}' failed during '${operation}': ${originalError.message}`;
}
}
else {
message = `Adapter '${adapter}' failed during '${operation}'`;
}
super(message, 'ADAPTER_ERROR', {
adapter,
operation,
originalError: originalError?.message
});
this.adapter = adapter;
this.operation = operation;
this.originalError = originalError;
this.name = 'AdapterError';
}
}
export class KubernetesError extends ExecutionError {
constructor(message, pod, namespace, container, details) {
super(message, 'KUBERNETES_ERROR', {
pod,
namespace,
container,
...details
});
this.pod = pod;
this.namespace = namespace;
this.container = container;
this.name = 'KubernetesError';
}
}
//# sourceMappingURL=error.js.map