zephyr-agent
Version:
Zephyr plugin agent
145 lines (142 loc) • 6.01 kB
JavaScript
import "node:module";
import { formatString, stripAnsi } from "zephyr-edge-contract";
import { ze_log } from "../logging/index.mjs";
import { blackBright, blue, bold, cyanBright, underline, whiteBright } from "../logging/picocolor.mjs";
import { redactString, safeStringifyForLogging, sanitizeForLogging } from "../security/redaction.mjs";
import { ZeErrorCategories, ZeErrors, isZeErrorEqual } from "./codes.mjs";
import * as __rspack_external_node_fs_1b05aee1 from "node:fs";
import * as __rspack_external_node_os_4f3c9d58 from "node:os";
import * as __rspack_external_node_path_806ed179 from "node:path";
import * as __rspack_external_node_util_ac04460e from "node:util";
const docsUrl = 'https://docs.zephyr-cloud.io/errors';
const discordUrl = 'https://zephyr-cloud.io/discord';
class ZephyrError extends Error {
code;
data;
template;
operation;
reason;
cause;
constructor(type, opts){
if (ZephyrError.is(opts?.cause)) {
if (isZeErrorEqual(type, ZeErrors.ERR_UNKNOWN)) return opts.cause;
if (!opts.data && opts.cause.data) {
opts.data = opts.cause.data;
opts.cause.data = void 0;
}
}
let message = type.message;
if (opts) message = formatString(type.message, opts);
super(message.trim());
this.code = ZephyrError.toZeCode(type);
if (opts) {
const { cause, data, operation, reason, ...template } = opts;
this.template = template;
this.data = data;
this.cause = cause;
this.operation = operation;
this.reason = reason ?? (ZephyrError.is(cause) ? cause.reason ?? cause.code : this.code);
}
this.reason ??= this.code;
if (process.env['VITE']) this._stack = this.stack;
}
static is(err, codeOrType) {
if (!(err instanceof ZephyrError)) return false;
if (!codeOrType) return true;
return ZephyrError.toZeCode(codeOrType) === err.code;
}
static withContext(error, operation) {
const zeError = ZephyrError.is(error) ? error : new ZephyrError(ZeErrors.ERR_UNKNOWN, {
message: error?.message || String(error),
cause: error
});
zeError.operation ??= operation;
return zeError;
}
static toZeCode({ id, kind }) {
const prefix = ZeErrorCategories[kind];
const paddedId = id.toString().padStart(3, '0');
const paddedPrefix = prefix.toString().padStart(2, '0');
return `ZE${paddedPrefix}${paddedId}`;
}
static fromZeCode(code) {
const prefix = code.slice(2, 4);
const id = code.slice(4);
let category;
for (const errorCategory of Object.keys(ZeErrorCategories))if (ZeErrorCategories[errorCategory] === prefix) {
category = errorCategory;
break;
}
if (!category) return ZeErrors.ERR_UNKNOWN;
for (const error of Object.values(ZeErrors))if (+error.id === +id && error.kind === category) return error;
return ZeErrors.ERR_UNKNOWN;
}
static format(error) {
const zeError = ZephyrError.is(error) ? error : new ZephyrError(ZeErrors.ERR_UNKNOWN, {
message: error?.message || String(error),
cause: error
});
const tmpFile = write_error_file(zeError);
const sanitizedData = sanitizeForLogging(zeError.data);
const inspected = 'object' == typeof sanitizedData ? __rspack_external_node_util_ac04460e.inspect(sanitizedData, false, 5, true) : sanitizedData;
const messages = [
`${bold(underline(zeError.code))}: ${redactString(zeError.message)}`,
formatDiagnosticContext(zeError),
`
Visit ${cyanBright(`${docsUrl}/${zeError.code.toLowerCase()}`)} for more information
Or join our ${blue('Discord')} server at ${cyanBright(discordUrl)}
`.trim(),
'{}' !== inspected && inspected,
tmpFile && blackBright(`Complete error details available at ${whiteBright(tmpFile)}`)
];
return redactString(messages.filter((x)=>!!x).map((x)=>x.trim()).join('\n\n'));
}
toJSON() {
return format_error(this);
}
}
function write_error_file(zeError) {
try {
const errorString = safeStringifyForLogging(format_error(zeError));
const errorExt = 'json';
ze_log.misc(errorString);
const tempPath = __rspack_external_node_path_806ed179.join(__rspack_external_node_os_4f3c9d58.tmpdir(), `ze${Math.round(10e9 * Math.random())}.${errorExt}`);
__rspack_external_node_fs_1b05aee1.writeFileSync(tempPath, errorString, 'utf8');
return tempPath;
} catch (error) {
ze_log.error('Failed writing error to temp file:', error);
return;
}
}
function format_error(err) {
if (!err) return;
const error = err;
return sanitizeForLogging({
name: error.name,
code: error.code,
operation: error.operation,
reason: error.reason,
template: void 0,
...error?.template,
data: error?.data,
message: error?.message,
stack: split_stack(error.stack, error.message),
cause: error.cause
});
}
function formatDiagnosticContext(error) {
if (!error.operation && error.reason === error.code) return;
const cause = ZephyrError.is(error.cause) ? error.cause : void 0;
const reasonMessage = cause && cause.code === error.reason ? redactString(cause.message) : void 0;
return [
error.operation && `Operation: ${error.operation}`,
error.reason && `Reason: ${error.reason}${reasonMessage ? `: ${reasonMessage}` : ''}`
].filter(Boolean).join('\n');
}
function split_stack(stack, message) {
if (!stack) return;
if (message) stack = stack.slice(`Error: ${message}\n`.length);
return stack.split('\n').map((line)=>stripAnsi(line.trim()));
}
export { ZephyrError, discordUrl, docsUrl };
//# sourceMappingURL=zephyr-error.mjs.map