export var ErrorCode;
(function (ErrorCode) {
ErrorCode['CONFIG_INVALID'] = 'CONFIG_INVALID';
ErrorCode['CONFIG_INCOMPLETE'] = 'CONFIG_INCOMPLETE';
ErrorCode['CONFIG_TYPE_MISMATCH'] = 'CONFIG_TYPE_MISMATCH';
ErrorCode['SOURCE_UNAVAILABLE'] = 'SOURCE_UNAVAILABLE';
ErrorCode['SOURCE_EMPTY'] = 'SOURCE_EMPTY';
ErrorCode['SOURCE_TOO_LARGE'] = 'SOURCE_TOO_LARGE';
ErrorCode['PARSE_FAILED'] = 'PARSE_FAILED';
ErrorCode['FORMAT_UNSUPPORTED'] = 'FORMAT_UNSUPPORTED';
ErrorCode['SCHEMA_VIOLATION'] = 'SCHEMA_VIOLATION';
ErrorCode['EXECUTION_FAILED'] = 'EXECUTION_FAILED';
ErrorCode['HANDLE_NOT_FOUND'] = 'HANDLE_NOT_FOUND';
ErrorCode['TYPE_MISMATCH'] = 'TYPE_MISMATCH';
ErrorCode['RESOURCE_LIMIT_EXCEEDED'] = 'RESOURCE_LIMIT_EXCEEDED';
ErrorCode['STATE_CORRUPTED'] = 'STATE_CORRUPTED';
ErrorCode['OPERATION_NOT_ALLOWED'] = 'OPERATION_NOT_ALLOWED';
ErrorCode['UNKNOWN'] = 'UNKNOWN';
})(ErrorCode || (ErrorCode = {}));
export var ErrorRecovery;
(function (ErrorRecovery) {
ErrorRecovery['RETRY'] = 'RETRY';
ErrorRecovery['RECONFIGURE'] = 'RECONFIGURE';
ErrorRecovery['REDUCE_SCOPE'] = 'REDUCE_SCOPE';
ErrorRecovery['VALIDATE_INPUT'] = 'VALIDATE_INPUT';
ErrorRecovery['FREE_RESOURCES'] = 'FREE_RESOURCES';
ErrorRecovery['REINITIALIZE'] = 'REINITIALIZE';
ErrorRecovery['CONTACT_SUPPORT'] = 'CONTACT_SUPPORT';
})(ErrorRecovery || (ErrorRecovery = {}));
export class Wasm4pmError extends Error {
constructor(message, code = ErrorCode.UNKNOWN, options) {
super(message);
this.name = 'Wasm4pmError';
this.code = code;
this.cause = options?.cause || null;
this.nextAction = options?.nextAction || ErrorRecovery.CONTACT_SUPPORT;
this.step = options?.step || null;
this.context = options?.context || {};
this.timestamp = new Date();
Object.setPrototypeOf(this, Wasm4pmError.prototype);
}
toJSON() {
return {
name: this.name,
message: this.message,
code: this.code,
step: this.step,
nextAction: this.nextAction,
context: this.context,
timestamp: this.timestamp.toISOString(),
cause: this.cause ? { message: this.cause.message, stack: this.cause.stack } : null,
stack: this.stack,
};
}
toString() {
const parts = [`[${this.code}]`, this.message];
if (this.step) {
parts.push(`(during: ${this.step})`);
}
return parts.join(' ');
}
}
export function classifyWasm4pmError(raw, context) {
if (!raw || typeof raw !== 'string') {
return ErrorCode.UNKNOWN;
}
const lowerRaw = raw.toLowerCase();
if (lowerRaw.includes('not found')) {
return ErrorCode.HANDLE_NOT_FOUND;
}
if (
lowerRaw.includes('is not a') ||
lowerRaw.includes('is not an') ||
lowerRaw.includes('object is not')
) {
return ErrorCode.TYPE_MISMATCH;
}
if (lowerRaw.includes('invalid json') || lowerRaw.includes('failed to parse')) {
return ErrorCode.PARSE_FAILED;
}
if (lowerRaw.includes('exceeds maximum') || lowerRaw.includes('exceeds limit')) {
return ErrorCode.RESOURCE_LIMIT_EXCEEDED;
}
if (
lowerRaw.includes('missing') ||
lowerRaw.includes('unknown operator') ||
lowerRaw.includes('must have') ||
lowerRaw.includes('field')
) {
return ErrorCode.CONFIG_INVALID;
}
if (
lowerRaw.includes('failed to lock') ||
lowerRaw.includes('failed to store') ||
lowerRaw.includes('failed to serialize')
) {
return ErrorCode.EXECUTION_FAILED;
}
if (lowerRaw.includes('failed to read') || lowerRaw.includes('not initialized')) {
return ErrorCode.SOURCE_UNAVAILABLE;
}
return ErrorCode.UNKNOWN;
}
export function wrapWasm4pmOperation(fn, context) {
try {
return fn();
} catch (err) {
const raw = err instanceof Error ? err.message : String(err);
const code = classifyWasm4pmError(raw, context);
let nextAction = ErrorRecovery.CONTACT_SUPPORT;
switch (code) {
case ErrorCode.CONFIG_INVALID:
case ErrorCode.CONFIG_INCOMPLETE:
case ErrorCode.CONFIG_TYPE_MISMATCH:
nextAction = ErrorRecovery.RECONFIGURE;
break;
case ErrorCode.SOURCE_UNAVAILABLE:
case ErrorCode.SOURCE_EMPTY:
nextAction = ErrorRecovery.VALIDATE_INPUT;
break;
case ErrorCode.RESOURCE_LIMIT_EXCEEDED:
nextAction = ErrorRecovery.REDUCE_SCOPE;
break;
case ErrorCode.HANDLE_NOT_FOUND:
case ErrorCode.STATE_CORRUPTED:
nextAction = ErrorRecovery.REINITIALIZE;
break;
case ErrorCode.PARSE_FAILED:
nextAction = ErrorRecovery.VALIDATE_INPUT;
break;
case ErrorCode.EXECUTION_FAILED:
nextAction = ErrorRecovery.RETRY;
break;
}
throw new Wasm4pmError(raw, code, {
cause: err instanceof Error ? err : null,
nextAction,
step: context?.step || undefined,
});
}
}
export function isWasm4pmError(err, code) {
if (!(err instanceof Wasm4pmError)) {
return false;
}
if (code !== undefined) {
return err.code === code;
}
return true;
}