function timestamp() { return new Date().toISOString(); } function formatError(error) { if (error instanceof Error) { return { name: error.name, message: error.message, stack: error.stack, ...(typeof error === "object" && error !== null && "$metadata" in error ? { metadata: error.$metadata } : {}), }; } return { value: String(error) }; } const consoleMethods = { info: console.log, warn: console.warn, error: console.error, debug: console.log, }; function log(level, step, message, details) { const prefix = `[${timestamp()}] [${level}] [${step}]`; const write = consoleMethods[level] ?? console.log; if (details !== undefined) { write(`${prefix} ${message}`, details); return; } write(`${prefix} ${message}`); } export const logger = { info(step, message, details) { log("info", step, message, details); }, warn(step, message, details) { log("warn", step, message, details); }, error(step, message, details) { log("error", step, message, details); }, debug(step, message, details) { log("debug", step, message, details); }, formatError, }; export async function runStep(step, fn) { logger.info(step, "starting"); try { const result = await fn(); logger.info(step, "completed"); return result; } catch (error) { logger.error(step, "failed", formatError(error)); throw error; } }