meld
Version:
Meld: A template language for LLM prompts
133 lines (118 loc) • 3.47 kB
text/typescript
import { MeldError, ErrorSeverity } from './MeldError.js';
export interface InterpreterLocation {
line: number;
column: number;
filePath?: string;
}
interface SerializedInterpreterError {
name: string;
message: string;
nodeType: string;
location?: InterpreterLocation;
filePath?: string;
cause?: string;
fullCauseMessage?: string;
severity: ErrorSeverity;
code?: string;
context?: {
filePath?: string;
nodeType?: string;
nodeCount?: number;
};
}
export interface InterpreterErrorContext {
filePath?: string;
nodeType?: string;
location?: InterpreterLocation;
parentFilePath?: string;
childFilePath?: string;
state?: {
filePath?: string;
nodeCount?: number;
};
}
export interface MeldInterpreterErrorOptions {
cause?: Error;
context?: InterpreterErrorContext;
severity?: ErrorSeverity;
code?: string;
}
/**
* Error thrown during interpretation of Meld content
*/
export class MeldInterpreterError extends MeldError {
public readonly nodeType: string;
public readonly location?: InterpreterLocation;
public readonly context?: InterpreterErrorContext;
constructor(
message: string,
nodeType: string,
location?: InterpreterLocation,
options: MeldInterpreterErrorOptions = {}
) {
// Format message with location if available
const locationStr = location
? ` at line ${location.line}, column ${location.column}${location.filePath ? ` in ${location.filePath}` : ''}`
: '';
// Interpreter errors are typically recoverable by default, but can be overridden
const severity = options.severity || ErrorSeverity.Recoverable;
super(`Interpreter error (${nodeType}): ${message}${locationStr}`, {
code: options.code || 'INTERPRETATION_FAILED',
filePath: location?.filePath || options.context?.filePath,
cause: options.cause,
severity,
context: {
...options.context,
nodeType,
location
}
});
this.name = 'MeldInterpreterError';
this.nodeType = nodeType;
this.location = location;
this.context = options.context;
// Ensure proper prototype chain for instanceof checks
Object.setPrototypeOf(this, MeldInterpreterError.prototype);
}
/**
* Access to the cause property of this error
*/
get cause(): Error | undefined {
return (this as any).errorCause;
}
/**
* Custom serialization to avoid circular references and include only essential info
*/
toJSON(): SerializedInterpreterError {
return {
name: this.name,
message: this.message,
nodeType: this.nodeType,
location: this.location,
filePath: this.filePath,
cause: this.cause?.message,
fullCauseMessage: this.cause ? this.getFullCauseMessage(this.cause) : undefined,
severity: this.severity,
code: this.code,
context: this.context ? {
filePath: this.context.filePath,
nodeType: this.context.nodeType,
nodeCount: this.context.state?.nodeCount
} : undefined
};
}
/**
* Get the full cause message chain
*/
private getFullCauseMessage(error: Error): string {
if (!error) return '';
let message = error.message || 'Unknown error';
if ('cause' in error) {
const cause = error.cause as unknown;
if (cause instanceof Error) {
message += ` -> ${this.getFullCauseMessage(cause)}`;
}
}
return message;
}
}