@autometa/errors
Advanced tools
| export interface AutomationErrorOptions { | ||
| readonly cause?: unknown; | ||
| } | ||
| /** | ||
| * Base error type emitted by Autometa utilities. | ||
| */ | ||
| export declare class AutomationError extends Error { | ||
| readonly cause?: unknown; | ||
| constructor(message: string, options?: AutomationErrorOptions); | ||
| static isAutomationError(value: unknown): value is AutomationError; | ||
| static wrap(value: unknown, fallbackMessage?: string): AutomationError; | ||
| } |
| export interface FormatErrorCausesOptions { | ||
| readonly includeStack?: boolean; | ||
| readonly describeValue?: (value: unknown) => string; | ||
| readonly maxDepth?: number; | ||
| } | ||
| export interface FormatErrorTreeOptions extends FormatErrorCausesOptions { | ||
| /** | ||
| * Text used to indent nested causes. Defaults to two spaces. | ||
| */ | ||
| readonly indent?: string; | ||
| /** | ||
| * Bullet prefix rendered before each error/value. Defaults to `•`. | ||
| */ | ||
| readonly bullet?: string; | ||
| } | ||
| export interface PrintErrorTreeOptions extends FormatErrorTreeOptions { | ||
| readonly writer?: (line: string) => void; | ||
| } | ||
| /** | ||
| * Produce a multi-line description summarising the error and its causes. | ||
| */ | ||
| export declare function formatErrorCauses(error: Error, options?: FormatErrorCausesOptions): string; | ||
| /** | ||
| * Render the error cause chain as an indented tree, suitable for logging. | ||
| */ | ||
| export declare function formatErrorTree(error: Error, options?: FormatErrorTreeOptions): string; | ||
| export declare function printErrorTree(error: Error, options?: PrintErrorTreeOptions): void; |
| import { AutomationError, type AutomationErrorOptions } from "./automation-error"; | ||
| export interface SourcePosition { | ||
| readonly line: number; | ||
| readonly column: number; | ||
| } | ||
| export interface SourceLocation { | ||
| readonly filePath: string; | ||
| readonly start: SourcePosition; | ||
| readonly end?: SourcePosition; | ||
| } | ||
| export interface GherkinContextSegment { | ||
| readonly featureName?: string; | ||
| readonly stepKeyword?: string; | ||
| readonly stepText?: string; | ||
| readonly location: SourceLocation; | ||
| } | ||
| export interface CodeContextSegment { | ||
| readonly functionName?: string; | ||
| readonly location: SourceLocation; | ||
| } | ||
| export type GherkinContextRole = "feature" | "rule" | "scenario" | "outline" | "example" | "step"; | ||
| export interface GherkinContextPathSegment { | ||
| readonly role: GherkinContextRole; | ||
| readonly keyword?: string; | ||
| readonly name?: string; | ||
| readonly text?: string; | ||
| readonly index?: number; | ||
| readonly location: SourceLocation; | ||
| } | ||
| export type GherkinStepStatus = "passed" | "failed" | "skipped"; | ||
| export interface GherkinStepSummary { | ||
| readonly keyword?: string; | ||
| readonly text?: string; | ||
| readonly location?: SourceLocation; | ||
| readonly status: GherkinStepStatus; | ||
| } | ||
| export interface GherkinErrorContext { | ||
| readonly gherkin?: GherkinContextSegment; | ||
| readonly code?: CodeContextSegment; | ||
| readonly path?: readonly GherkinContextPathSegment[]; | ||
| readonly steps?: readonly GherkinStepSummary[]; | ||
| } | ||
| export interface GherkinStepErrorOptions extends AutomationErrorOptions { | ||
| readonly context: GherkinErrorContext; | ||
| } | ||
| /** | ||
| * Error subtype used to wrap failures that occur while executing a Gherkin step. | ||
| */ | ||
| export declare class GherkinStepError extends AutomationError { | ||
| constructor(message: string, options: GherkinStepErrorOptions); | ||
| get context(): GherkinErrorContext; | ||
| } | ||
| export declare function isGherkinStepError(value: unknown): value is GherkinStepError; | ||
| export declare function getGherkinErrorContext(value: unknown): GherkinErrorContext | undefined; |
+327
| 'use strict'; | ||
| // src/automation-error.ts | ||
| var AutomationError = class _AutomationError extends Error { | ||
| constructor(message, options = {}) { | ||
| const { cause } = options; | ||
| super(message); | ||
| this.name = "AutomationError"; | ||
| if (cause !== void 0) { | ||
| Object.defineProperty(this, "cause", { | ||
| configurable: true, | ||
| enumerable: false, | ||
| writable: false, | ||
| value: cause | ||
| }); | ||
| } | ||
| } | ||
| static isAutomationError(value) { | ||
| return value instanceof _AutomationError; | ||
| } | ||
| static wrap(value, fallbackMessage = "Unknown error") { | ||
| if (value instanceof _AutomationError) { | ||
| return value; | ||
| } | ||
| if (value instanceof Error) { | ||
| return new _AutomationError(value.message, { cause: value }); | ||
| } | ||
| if (typeof value === "string") { | ||
| return new _AutomationError(value); | ||
| } | ||
| return new _AutomationError(fallbackMessage, { cause: value }); | ||
| } | ||
| }; | ||
| // src/gherkin-error.ts | ||
| var CONTEXT_SYMBOL = Symbol.for("autometa.gherkinErrorContext"); | ||
| function freezePosition(position) { | ||
| return Object.freeze({ | ||
| line: position.line, | ||
| column: position.column | ||
| }); | ||
| } | ||
| function freezeLocation(location) { | ||
| return Object.freeze({ | ||
| filePath: location.filePath, | ||
| start: freezePosition(location.start), | ||
| ...location.end ? { end: freezePosition(location.end) } : {} | ||
| }); | ||
| } | ||
| function freezeGherkinSegment(segment) { | ||
| return Object.freeze({ | ||
| location: freezeLocation(segment.location), | ||
| ...segment.featureName !== void 0 ? { featureName: segment.featureName } : {}, | ||
| ...segment.stepKeyword !== void 0 ? { stepKeyword: segment.stepKeyword } : {}, | ||
| ...segment.stepText !== void 0 ? { stepText: segment.stepText } : {} | ||
| }); | ||
| } | ||
| function freezeCodeSegment(segment) { | ||
| return Object.freeze({ | ||
| location: freezeLocation(segment.location), | ||
| ...segment.functionName !== void 0 ? { functionName: segment.functionName } : {} | ||
| }); | ||
| } | ||
| function freezePathSegment(segment) { | ||
| return Object.freeze({ | ||
| role: segment.role, | ||
| location: freezeLocation(segment.location), | ||
| ...segment.keyword !== void 0 ? { keyword: segment.keyword } : {}, | ||
| ...segment.name !== void 0 ? { name: segment.name } : {}, | ||
| ...segment.text !== void 0 ? { text: segment.text } : {}, | ||
| ...segment.index !== void 0 ? { index: segment.index } : {} | ||
| }); | ||
| } | ||
| function freezePath(path) { | ||
| return Object.freeze(path.map((segment) => freezePathSegment(segment))); | ||
| } | ||
| function freezeStepSummary(step) { | ||
| return Object.freeze({ | ||
| status: step.status, | ||
| ...step.keyword !== void 0 ? { keyword: step.keyword } : {}, | ||
| ...step.text !== void 0 ? { text: step.text } : {}, | ||
| ...step.location ? { location: freezeLocation(step.location) } : {} | ||
| }); | ||
| } | ||
| function freezeSteps(steps) { | ||
| return Object.freeze(steps.map((step) => freezeStepSummary(step))); | ||
| } | ||
| function freezeContext(context) { | ||
| return Object.freeze({ | ||
| ...context.gherkin ? { gherkin: freezeGherkinSegment(context.gherkin) } : {}, | ||
| ...context.code ? { code: freezeCodeSegment(context.code) } : {}, | ||
| ...context.path ? { path: freezePath(context.path) } : {}, | ||
| ...context.steps ? { steps: freezeSteps(context.steps) } : {} | ||
| }); | ||
| } | ||
| function setContext(target, context) { | ||
| Object.defineProperty(target, CONTEXT_SYMBOL, { | ||
| configurable: false, | ||
| enumerable: false, | ||
| writable: false, | ||
| value: freezeContext(context) | ||
| }); | ||
| } | ||
| function getContext(target) { | ||
| if (!target || typeof target !== "object") { | ||
| return void 0; | ||
| } | ||
| return Reflect.get(target, CONTEXT_SYMBOL); | ||
| } | ||
| var GherkinStepError = class extends AutomationError { | ||
| constructor(message, options) { | ||
| const { context, ...rest } = options; | ||
| super(message, rest); | ||
| this.name = "GherkinStepError"; | ||
| setContext(this, context); | ||
| } | ||
| get context() { | ||
| const context = getContext(this); | ||
| if (!context) { | ||
| throw new Error("Missing Gherkin context for error instance"); | ||
| } | ||
| return context; | ||
| } | ||
| }; | ||
| function isGherkinStepError(value) { | ||
| return value instanceof GherkinStepError; | ||
| } | ||
| function getGherkinErrorContext(value) { | ||
| const visited = /* @__PURE__ */ new Set(); | ||
| let current = value; | ||
| while (current instanceof Error && !visited.has(current)) { | ||
| visited.add(current); | ||
| const context = getContext(current); | ||
| if (context) { | ||
| return context; | ||
| } | ||
| if (!("cause" in current)) { | ||
| break; | ||
| } | ||
| const cause = current.cause; | ||
| if (!(cause instanceof Error)) { | ||
| break; | ||
| } | ||
| current = cause; | ||
| } | ||
| return void 0; | ||
| } | ||
| // src/formatter.ts | ||
| function hasCause(error) { | ||
| return "cause" in error; | ||
| } | ||
| function formatError(error, includeStack) { | ||
| const header = `${error.name}: ${error.message}`; | ||
| if (!includeStack) { | ||
| return header; | ||
| } | ||
| const stack = error.stack ?? "<no stack trace available>"; | ||
| return `${header} | ||
| Stacktrace: | ||
| ${stack}`; | ||
| } | ||
| function describeUnknown(value) { | ||
| if (value instanceof Error) { | ||
| return `${value.name}: ${value.message}`; | ||
| } | ||
| if (typeof value === "string") { | ||
| return value; | ||
| } | ||
| try { | ||
| return JSON.stringify(value); | ||
| } catch { | ||
| return String(value); | ||
| } | ||
| } | ||
| function buildErrorChain(root, describeValue, maxDepth) { | ||
| const entries = []; | ||
| const visited = /* @__PURE__ */ new Set(); | ||
| let current = root; | ||
| let depth = 0; | ||
| while (current) { | ||
| entries.push({ kind: "error", error: current, depth }); | ||
| if (depth >= maxDepth) { | ||
| if (hasCause(current) && current.cause !== void 0) { | ||
| entries.push({ | ||
| kind: "notice", | ||
| message: "[max depth reached]", | ||
| depth: depth + 1 | ||
| }); | ||
| } | ||
| break; | ||
| } | ||
| visited.add(current); | ||
| if (!hasCause(current) || current.cause === void 0) { | ||
| break; | ||
| } | ||
| const cause = current.cause; | ||
| if (!(cause instanceof Error)) { | ||
| entries.push({ | ||
| kind: "value", | ||
| value: describeValue(cause), | ||
| depth: depth + 1 | ||
| }); | ||
| break; | ||
| } | ||
| if (visited.has(cause)) { | ||
| entries.push({ | ||
| kind: "notice", | ||
| message: "[cycle detected in error causes]", | ||
| depth: depth + 1 | ||
| }); | ||
| break; | ||
| } | ||
| current = cause; | ||
| depth += 1; | ||
| } | ||
| return entries; | ||
| } | ||
| function formatErrorCauses(error, options = {}) { | ||
| const { | ||
| includeStack = true, | ||
| describeValue = describeUnknown, | ||
| maxDepth = Number.POSITIVE_INFINITY | ||
| } = options; | ||
| const entries = buildErrorChain(error, describeValue, maxDepth); | ||
| const segments = entries.map((entry) => { | ||
| if (entry.kind === "error") { | ||
| return formatError(entry.error, includeStack); | ||
| } | ||
| return entry.kind === "value" ? entry.value : entry.message; | ||
| }); | ||
| return segments.join("\nCause:\n"); | ||
| } | ||
| function formatErrorTree(error, options = {}) { | ||
| const { | ||
| includeStack = true, | ||
| describeValue = describeUnknown, | ||
| maxDepth = Number.POSITIVE_INFINITY, | ||
| indent = " ", | ||
| bullet = "\u2022" | ||
| } = options; | ||
| const entries = buildErrorChain(error, describeValue, maxDepth); | ||
| const lines = []; | ||
| for (const entry of entries) { | ||
| const content = entry.kind === "error" ? formatError(entry.error, includeStack) : entry.kind === "value" ? entry.value : entry.message; | ||
| appendIndentedContent(lines, content, entry.depth, indent, bullet); | ||
| } | ||
| return lines.join("\n"); | ||
| } | ||
| function printErrorTree(error, options = {}) { | ||
| const { writer = (line) => console.error(line), ...rest } = options; | ||
| const formatted = formatErrorTree(error, rest); | ||
| for (const line of formatted.split("\n")) { | ||
| writer(line); | ||
| } | ||
| } | ||
| function appendIndentedContent(lines, content, depth, indent, bullet) { | ||
| const padding = indent.repeat(depth); | ||
| const parts = content.split("\n"); | ||
| lines.push(`${padding}${bullet} ${parts[0]}`); | ||
| for (let index = 1; index < parts.length; index += 1) { | ||
| lines.push(`${padding}${indent}${parts[index]}`); | ||
| } | ||
| } | ||
| // src/raise.ts | ||
| function assignCause(instance, cause) { | ||
| Object.defineProperty(instance, "cause", { | ||
| configurable: true, | ||
| enumerable: false, | ||
| writable: false, | ||
| value: cause | ||
| }); | ||
| } | ||
| function supportsCauseSignature(ctor) { | ||
| try { | ||
| new ctor("probe", { cause: void 0 }); | ||
| return true; | ||
| } catch { | ||
| return false; | ||
| } | ||
| } | ||
| function buildError(type, message, options) { | ||
| if (supportsCauseSignature(type)) { | ||
| return new type(message, options); | ||
| } | ||
| const instance = new type(message); | ||
| if (options.cause !== void 0) { | ||
| assignCause(instance, options.cause); | ||
| } | ||
| return instance; | ||
| } | ||
| function raise(message, options = {}) { | ||
| const { type, cause } = options; | ||
| const automationOptions = cause === void 0 ? {} : { cause }; | ||
| const error = type ? buildError(type, message, automationOptions) : new AutomationError(message, automationOptions); | ||
| throw error; | ||
| } | ||
| // src/safe-error.ts | ||
| function safe(action, ...args) { | ||
| try { | ||
| return { ok: true, value: action(...args) }; | ||
| } catch (error) { | ||
| return { ok: false, error: AutomationError.wrap(error) }; | ||
| } | ||
| } | ||
| async function safeAsync(action, ...args) { | ||
| try { | ||
| return { ok: true, value: await action(...args) }; | ||
| } catch (error) { | ||
| return { ok: false, error: AutomationError.wrap(error) }; | ||
| } | ||
| } | ||
| exports.AutomationError = AutomationError; | ||
| exports.GherkinStepError = GherkinStepError; | ||
| exports.formatErrorCauses = formatErrorCauses; | ||
| exports.formatErrorTree = formatErrorTree; | ||
| exports.getGherkinErrorContext = getGherkinErrorContext; | ||
| exports.isGherkinStepError = isGherkinStepError; | ||
| exports.printErrorTree = printErrorTree; | ||
| exports.raise = raise; | ||
| exports.safe = safe; | ||
| exports.safeAsync = safeAsync; | ||
| //# sourceMappingURL=out.js.map | ||
| //# sourceMappingURL=index.cjs.map |
| {"version":3,"sources":["../src/automation-error.ts","../src/gherkin-error.ts","../src/formatter.ts","../src/raise.ts","../src/safe-error.ts"],"names":[],"mappings":"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","sourcesContent":["export interface AutomationErrorOptions {\n readonly cause?: unknown;\n}\n\n/**\n * Base error type emitted by Autometa utilities.\n */\nexport class AutomationError extends Error {\n declare readonly cause?: unknown;\n\n constructor(message: string, options: AutomationErrorOptions = {}) {\n const { cause } = options;\n super(message);\n this.name = \"AutomationError\";\n if (cause !== undefined) {\n Object.defineProperty(this, \"cause\", {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cause,\n });\n }\n }\n\n static isAutomationError(value: unknown): value is AutomationError {\n return value instanceof AutomationError;\n }\n\n static wrap(value: unknown, fallbackMessage = \"Unknown error\"): AutomationError {\n if (value instanceof AutomationError) {\n return value;\n }\n\n if (value instanceof Error) {\n return new AutomationError(value.message, { cause: value });\n }\n\n if (typeof value === \"string\") {\n return new AutomationError(value);\n }\n\n return new AutomationError(fallbackMessage, { cause: value });\n }\n}\n","import { AutomationError, type AutomationErrorOptions } from \"./automation-error\";\n\nconst CONTEXT_SYMBOL = Symbol.for(\"autometa.gherkinErrorContext\");\n\nexport interface SourcePosition {\n readonly line: number;\n readonly column: number;\n}\n\nexport interface SourceLocation {\n readonly filePath: string;\n readonly start: SourcePosition;\n readonly end?: SourcePosition;\n}\n\nexport interface GherkinContextSegment {\n readonly featureName?: string;\n readonly stepKeyword?: string;\n readonly stepText?: string;\n readonly location: SourceLocation;\n}\n\nexport interface CodeContextSegment {\n readonly functionName?: string;\n readonly location: SourceLocation;\n}\n\nexport type GherkinContextRole =\n | \"feature\"\n | \"rule\"\n | \"scenario\"\n | \"outline\"\n | \"example\"\n | \"step\";\n\nexport interface GherkinContextPathSegment {\n readonly role: GherkinContextRole;\n readonly keyword?: string;\n readonly name?: string;\n readonly text?: string;\n readonly index?: number;\n readonly location: SourceLocation;\n}\n\nexport type GherkinStepStatus = \"passed\" | \"failed\" | \"skipped\";\n\nexport interface GherkinStepSummary {\n readonly keyword?: string;\n readonly text?: string;\n readonly location?: SourceLocation;\n readonly status: GherkinStepStatus;\n}\n\nexport interface GherkinErrorContext {\n readonly gherkin?: GherkinContextSegment;\n readonly code?: CodeContextSegment;\n readonly path?: readonly GherkinContextPathSegment[];\n readonly steps?: readonly GherkinStepSummary[];\n}\n\nexport interface GherkinStepErrorOptions extends AutomationErrorOptions {\n readonly context: GherkinErrorContext;\n}\n\nfunction freezePosition(position: SourcePosition): SourcePosition {\n return Object.freeze({\n line: position.line,\n column: position.column,\n });\n}\n\nfunction freezeLocation(location: SourceLocation): SourceLocation {\n return Object.freeze({\n filePath: location.filePath,\n start: freezePosition(location.start),\n ...(location.end ? { end: freezePosition(location.end) } : {}),\n });\n}\n\nfunction freezeGherkinSegment(segment: GherkinContextSegment): GherkinContextSegment {\n return Object.freeze({\n location: freezeLocation(segment.location),\n ...(segment.featureName !== undefined ? { featureName: segment.featureName } : {}),\n ...(segment.stepKeyword !== undefined ? { stepKeyword: segment.stepKeyword } : {}),\n ...(segment.stepText !== undefined ? { stepText: segment.stepText } : {}),\n });\n}\n\nfunction freezeCodeSegment(segment: CodeContextSegment): CodeContextSegment {\n return Object.freeze({\n location: freezeLocation(segment.location),\n ...(segment.functionName !== undefined ? { functionName: segment.functionName } : {}),\n });\n}\n\nfunction freezePathSegment(segment: GherkinContextPathSegment): GherkinContextPathSegment {\n return Object.freeze({\n role: segment.role,\n location: freezeLocation(segment.location),\n ...(segment.keyword !== undefined ? { keyword: segment.keyword } : {}),\n ...(segment.name !== undefined ? { name: segment.name } : {}),\n ...(segment.text !== undefined ? { text: segment.text } : {}),\n ...(segment.index !== undefined ? { index: segment.index } : {}),\n });\n}\n\nfunction freezePath(\n path: readonly GherkinContextPathSegment[]\n): readonly GherkinContextPathSegment[] {\n return Object.freeze(path.map((segment) => freezePathSegment(segment)));\n}\n\nfunction freezeStepSummary(step: GherkinStepSummary): GherkinStepSummary {\n return Object.freeze({\n status: step.status,\n ...(step.keyword !== undefined ? { keyword: step.keyword } : {}),\n ...(step.text !== undefined ? { text: step.text } : {}),\n ...(step.location ? { location: freezeLocation(step.location) } : {}),\n });\n}\n\nfunction freezeSteps(\n steps: readonly GherkinStepSummary[]\n): readonly GherkinStepSummary[] {\n return Object.freeze(steps.map((step) => freezeStepSummary(step)));\n}\n\nfunction freezeContext(context: GherkinErrorContext): GherkinErrorContext {\n return Object.freeze({\n ...(context.gherkin ? { gherkin: freezeGherkinSegment(context.gherkin) } : {}),\n ...(context.code ? { code: freezeCodeSegment(context.code) } : {}),\n ...(context.path ? { path: freezePath(context.path) } : {}),\n ...(context.steps ? { steps: freezeSteps(context.steps) } : {}),\n });\n}\n\nfunction setContext(target: object, context: GherkinErrorContext): void {\n Object.defineProperty(target, CONTEXT_SYMBOL, {\n configurable: false,\n enumerable: false,\n writable: false,\n value: freezeContext(context),\n });\n}\n\nfunction getContext(target: unknown): GherkinErrorContext | undefined {\n if (!target || typeof target !== \"object\") {\n return undefined;\n }\n return Reflect.get(target, CONTEXT_SYMBOL) as GherkinErrorContext | undefined;\n}\n\n/**\n * Error subtype used to wrap failures that occur while executing a Gherkin step.\n */\nexport class GherkinStepError extends AutomationError {\n constructor(message: string, options: GherkinStepErrorOptions) {\n const { context, ...rest } = options;\n super(message, rest);\n this.name = \"GherkinStepError\";\n setContext(this, context);\n }\n\n get context(): GherkinErrorContext {\n const context = getContext(this);\n if (!context) {\n throw new Error(\"Missing Gherkin context for error instance\");\n }\n return context;\n }\n}\n\nexport function isGherkinStepError(value: unknown): value is GherkinStepError {\n return value instanceof GherkinStepError;\n}\n\ninterface ErrorWithCause extends Error {\n readonly cause?: unknown;\n}\n\nexport function getGherkinErrorContext(value: unknown): GherkinErrorContext | undefined {\n const visited = new Set<Error>();\n let current: unknown = value;\n\n while (current instanceof Error && !visited.has(current)) {\n visited.add(current);\n const context = getContext(current);\n if (context) {\n return context;\n }\n\n if (!(\"cause\" in current)) {\n break;\n }\n\n const cause = (current as ErrorWithCause).cause;\n if (!(cause instanceof Error)) {\n break;\n }\n current = cause;\n }\n\n return undefined;\n}\n","export interface FormatErrorCausesOptions {\n readonly includeStack?: boolean;\n readonly describeValue?: (value: unknown) => string;\n readonly maxDepth?: number;\n}\n\nexport interface FormatErrorTreeOptions extends FormatErrorCausesOptions {\n /**\n * Text used to indent nested causes. Defaults to two spaces.\n */\n readonly indent?: string;\n /**\n * Bullet prefix rendered before each error/value. Defaults to `•`.\n */\n readonly bullet?: string;\n}\n\nexport interface PrintErrorTreeOptions extends FormatErrorTreeOptions {\n readonly writer?: (line: string) => void;\n}\n\ninterface ErrorWithCause extends Error {\n readonly cause?: unknown;\n}\n\ninterface ErrorChainEntryError {\n readonly kind: \"error\";\n readonly error: Error;\n readonly depth: number;\n}\n\ninterface ErrorChainEntryValue {\n readonly kind: \"value\";\n readonly value: string;\n readonly depth: number;\n}\n\ninterface ErrorChainEntryNotice {\n readonly kind: \"notice\";\n readonly message: string;\n readonly depth: number;\n}\n\ntype ErrorChainEntry =\n | ErrorChainEntryError\n | ErrorChainEntryValue\n | ErrorChainEntryNotice;\n\nfunction hasCause(error: Error): error is ErrorWithCause {\n return \"cause\" in error;\n}\n\nfunction formatError(error: Error, includeStack: boolean): string {\n const header = `${error.name}: ${error.message}`;\n if (!includeStack) {\n return header;\n }\n const stack = error.stack ?? \"<no stack trace available>\";\n return `${header}\\nStacktrace:\\n${stack}`;\n}\n\nfunction describeUnknown(value: unknown): string {\n if (value instanceof Error) {\n return `${value.name}: ${value.message}`;\n }\n if (typeof value === \"string\") {\n return value;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction buildErrorChain(\n root: Error,\n describeValue: (value: unknown) => string,\n maxDepth: number\n): ErrorChainEntry[] {\n const entries: ErrorChainEntry[] = [];\n const visited = new Set<Error>();\n\n let current: ErrorWithCause | undefined = root;\n let depth = 0;\n\n while (current) {\n entries.push({ kind: \"error\", error: current, depth });\n\n if (depth >= maxDepth) {\n if (hasCause(current) && current.cause !== undefined) {\n entries.push({\n kind: \"notice\",\n message: \"[max depth reached]\",\n depth: depth + 1,\n });\n }\n break;\n }\n\n visited.add(current);\n\n if (!hasCause(current) || current.cause === undefined) {\n break;\n }\n\n const cause: unknown = current.cause;\n if (!(cause instanceof Error)) {\n entries.push({\n kind: \"value\",\n value: describeValue(cause),\n depth: depth + 1,\n });\n break;\n }\n\n if (visited.has(cause)) {\n entries.push({\n kind: \"notice\",\n message: \"[cycle detected in error causes]\",\n depth: depth + 1,\n });\n break;\n }\n\n current = cause;\n depth += 1;\n }\n\n return entries;\n}\n\n/**\n * Produce a multi-line description summarising the error and its causes.\n */\nexport function formatErrorCauses(error: Error, options: FormatErrorCausesOptions = {}): string {\n const {\n includeStack = true,\n describeValue = describeUnknown,\n maxDepth = Number.POSITIVE_INFINITY,\n } = options;\n\n const entries = buildErrorChain(error, describeValue, maxDepth);\n const segments = entries.map((entry) => {\n if (entry.kind === \"error\") {\n return formatError(entry.error, includeStack);\n }\n return entry.kind === \"value\" ? entry.value : entry.message;\n });\n\n return segments.join(\"\\nCause:\\n\");\n}\n\n/**\n * Render the error cause chain as an indented tree, suitable for logging.\n */\nexport function formatErrorTree(error: Error, options: FormatErrorTreeOptions = {}): string {\n const {\n includeStack = true,\n describeValue = describeUnknown,\n maxDepth = Number.POSITIVE_INFINITY,\n indent = \" \",\n bullet = \"•\",\n } = options;\n\n const entries = buildErrorChain(error, describeValue, maxDepth);\n const lines: string[] = [];\n\n for (const entry of entries) {\n const content =\n entry.kind === \"error\"\n ? formatError(entry.error, includeStack)\n : entry.kind === \"value\"\n ? entry.value\n : entry.message;\n\n appendIndentedContent(lines, content, entry.depth, indent, bullet);\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function printErrorTree(error: Error, options: PrintErrorTreeOptions = {}): void {\n const { writer = (line: string) => console.error(line), ...rest } = options;\n const formatted = formatErrorTree(error, rest);\n for (const line of formatted.split(\"\\n\")) {\n writer(line);\n }\n}\n\nfunction appendIndentedContent(\n lines: string[],\n content: string,\n depth: number,\n indent: string,\n bullet: string\n) {\n const padding = indent.repeat(depth);\n const parts = content.split(\"\\n\");\n lines.push(`${padding}${bullet} ${parts[0]}`);\n for (let index = 1; index < parts.length; index += 1) {\n lines.push(`${padding}${indent}${parts[index]}`);\n }\n}\n","import { AutomationError, type AutomationErrorOptions } from \"./automation-error\";\n\ntype AutomationErrorConstructor<TError extends Error> = new (\n message: string,\n options?: AutomationErrorOptions\n) => TError;\n\nexport interface RaiseOptions<TError extends Error = AutomationError> extends AutomationErrorOptions {\n readonly type?: AutomationErrorConstructor<TError> | (new (message: string) => TError);\n}\n\nfunction assignCause(instance: Error, cause: unknown): void {\n Object.defineProperty(instance, \"cause\", {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cause,\n });\n}\n\nfunction supportsCauseSignature<TError extends Error>(ctor: AutomationErrorConstructor<TError>): boolean {\n try {\n // eslint-disable-next-line no-new\n new ctor(\"probe\", { cause: undefined });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction buildError<TError extends Error>(\n type: AutomationErrorConstructor<TError> | (new (message: string) => TError),\n message: string,\n options: AutomationErrorOptions\n): TError {\n if (supportsCauseSignature(type as AutomationErrorConstructor<TError>)) {\n return new (type as AutomationErrorConstructor<TError>)(message, options);\n }\n\n const instance = new type(message);\n if (options.cause !== undefined) {\n assignCause(instance, options.cause);\n }\n return instance;\n}\n\n/**\n * Construct and throw an {@link AutomationError} (or custom error) with the provided message.\n */\nexport function raise<TError extends Error = AutomationError>(\n message: string,\n options: RaiseOptions<TError> = {}\n): never {\n const { type, cause } = options;\n const automationOptions: AutomationErrorOptions = cause === undefined ? {} : { cause };\n\n const error = type ? buildError(type, message, automationOptions) : new AutomationError(message, automationOptions);\n throw error;\n}\n","import { AutomationError } from \"./automation-error\";\n\nexport interface SafeOk<T> {\n readonly ok: true;\n readonly value: T;\n}\n\nexport interface SafeErr {\n readonly ok: false;\n readonly error: AutomationError;\n}\n\nexport type SafeResult<T> = SafeOk<T> | SafeErr;\n\n/**\n * Execute the callback and capture any thrown error as an {@link AutomationError}.\n */\nexport function safe<TArgs extends unknown[], TResult>(\n action: (...args: TArgs) => TResult,\n ...args: TArgs\n): SafeResult<TResult> {\n try {\n return { ok: true, value: action(...args) };\n } catch (error) {\n return { ok: false, error: AutomationError.wrap(error) };\n }\n}\n\n/**\n * Async variant of {@link safe}. Returns a promise that resolves with the value\n * or the captured {@link AutomationError}.\n */\nexport async function safeAsync<TArgs extends unknown[], TResult>(\n action: (...args: TArgs) => Promise<TResult> | TResult,\n ...args: TArgs\n): Promise<SafeResult<TResult>> {\n try {\n return { ok: true, value: await action(...args) };\n } catch (error) {\n return { ok: false, error: AutomationError.wrap(error) };\n }\n}\n"]} |
| {"version":3,"sources":["../src/automation-error.ts","../src/gherkin-error.ts","../src/formatter.ts","../src/raise.ts","../src/safe-error.ts"],"names":[],"mappings":"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","sourcesContent":["export interface AutomationErrorOptions {\n readonly cause?: unknown;\n}\n\n/**\n * Base error type emitted by Autometa utilities.\n */\nexport class AutomationError extends Error {\n declare readonly cause?: unknown;\n\n constructor(message: string, options: AutomationErrorOptions = {}) {\n const { cause } = options;\n super(message);\n this.name = \"AutomationError\";\n if (cause !== undefined) {\n Object.defineProperty(this, \"cause\", {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cause,\n });\n }\n }\n\n static isAutomationError(value: unknown): value is AutomationError {\n return value instanceof AutomationError;\n }\n\n static wrap(value: unknown, fallbackMessage = \"Unknown error\"): AutomationError {\n if (value instanceof AutomationError) {\n return value;\n }\n\n if (value instanceof Error) {\n return new AutomationError(value.message, { cause: value });\n }\n\n if (typeof value === \"string\") {\n return new AutomationError(value);\n }\n\n return new AutomationError(fallbackMessage, { cause: value });\n }\n}\n","import { AutomationError, type AutomationErrorOptions } from \"./automation-error\";\n\nconst CONTEXT_SYMBOL = Symbol.for(\"autometa.gherkinErrorContext\");\n\nexport interface SourcePosition {\n readonly line: number;\n readonly column: number;\n}\n\nexport interface SourceLocation {\n readonly filePath: string;\n readonly start: SourcePosition;\n readonly end?: SourcePosition;\n}\n\nexport interface GherkinContextSegment {\n readonly featureName?: string;\n readonly stepKeyword?: string;\n readonly stepText?: string;\n readonly location: SourceLocation;\n}\n\nexport interface CodeContextSegment {\n readonly functionName?: string;\n readonly location: SourceLocation;\n}\n\nexport type GherkinContextRole =\n | \"feature\"\n | \"rule\"\n | \"scenario\"\n | \"outline\"\n | \"example\"\n | \"step\";\n\nexport interface GherkinContextPathSegment {\n readonly role: GherkinContextRole;\n readonly keyword?: string;\n readonly name?: string;\n readonly text?: string;\n readonly index?: number;\n readonly location: SourceLocation;\n}\n\nexport type GherkinStepStatus = \"passed\" | \"failed\" | \"skipped\";\n\nexport interface GherkinStepSummary {\n readonly keyword?: string;\n readonly text?: string;\n readonly location?: SourceLocation;\n readonly status: GherkinStepStatus;\n}\n\nexport interface GherkinErrorContext {\n readonly gherkin?: GherkinContextSegment;\n readonly code?: CodeContextSegment;\n readonly path?: readonly GherkinContextPathSegment[];\n readonly steps?: readonly GherkinStepSummary[];\n}\n\nexport interface GherkinStepErrorOptions extends AutomationErrorOptions {\n readonly context: GherkinErrorContext;\n}\n\nfunction freezePosition(position: SourcePosition): SourcePosition {\n return Object.freeze({\n line: position.line,\n column: position.column,\n });\n}\n\nfunction freezeLocation(location: SourceLocation): SourceLocation {\n return Object.freeze({\n filePath: location.filePath,\n start: freezePosition(location.start),\n ...(location.end ? { end: freezePosition(location.end) } : {}),\n });\n}\n\nfunction freezeGherkinSegment(segment: GherkinContextSegment): GherkinContextSegment {\n return Object.freeze({\n location: freezeLocation(segment.location),\n ...(segment.featureName !== undefined ? { featureName: segment.featureName } : {}),\n ...(segment.stepKeyword !== undefined ? { stepKeyword: segment.stepKeyword } : {}),\n ...(segment.stepText !== undefined ? { stepText: segment.stepText } : {}),\n });\n}\n\nfunction freezeCodeSegment(segment: CodeContextSegment): CodeContextSegment {\n return Object.freeze({\n location: freezeLocation(segment.location),\n ...(segment.functionName !== undefined ? { functionName: segment.functionName } : {}),\n });\n}\n\nfunction freezePathSegment(segment: GherkinContextPathSegment): GherkinContextPathSegment {\n return Object.freeze({\n role: segment.role,\n location: freezeLocation(segment.location),\n ...(segment.keyword !== undefined ? { keyword: segment.keyword } : {}),\n ...(segment.name !== undefined ? { name: segment.name } : {}),\n ...(segment.text !== undefined ? { text: segment.text } : {}),\n ...(segment.index !== undefined ? { index: segment.index } : {}),\n });\n}\n\nfunction freezePath(\n path: readonly GherkinContextPathSegment[]\n): readonly GherkinContextPathSegment[] {\n return Object.freeze(path.map((segment) => freezePathSegment(segment)));\n}\n\nfunction freezeStepSummary(step: GherkinStepSummary): GherkinStepSummary {\n return Object.freeze({\n status: step.status,\n ...(step.keyword !== undefined ? { keyword: step.keyword } : {}),\n ...(step.text !== undefined ? { text: step.text } : {}),\n ...(step.location ? { location: freezeLocation(step.location) } : {}),\n });\n}\n\nfunction freezeSteps(\n steps: readonly GherkinStepSummary[]\n): readonly GherkinStepSummary[] {\n return Object.freeze(steps.map((step) => freezeStepSummary(step)));\n}\n\nfunction freezeContext(context: GherkinErrorContext): GherkinErrorContext {\n return Object.freeze({\n ...(context.gherkin ? { gherkin: freezeGherkinSegment(context.gherkin) } : {}),\n ...(context.code ? { code: freezeCodeSegment(context.code) } : {}),\n ...(context.path ? { path: freezePath(context.path) } : {}),\n ...(context.steps ? { steps: freezeSteps(context.steps) } : {}),\n });\n}\n\nfunction setContext(target: object, context: GherkinErrorContext): void {\n Object.defineProperty(target, CONTEXT_SYMBOL, {\n configurable: false,\n enumerable: false,\n writable: false,\n value: freezeContext(context),\n });\n}\n\nfunction getContext(target: unknown): GherkinErrorContext | undefined {\n if (!target || typeof target !== \"object\") {\n return undefined;\n }\n return Reflect.get(target, CONTEXT_SYMBOL) as GherkinErrorContext | undefined;\n}\n\n/**\n * Error subtype used to wrap failures that occur while executing a Gherkin step.\n */\nexport class GherkinStepError extends AutomationError {\n constructor(message: string, options: GherkinStepErrorOptions) {\n const { context, ...rest } = options;\n super(message, rest);\n this.name = \"GherkinStepError\";\n setContext(this, context);\n }\n\n get context(): GherkinErrorContext {\n const context = getContext(this);\n if (!context) {\n throw new Error(\"Missing Gherkin context for error instance\");\n }\n return context;\n }\n}\n\nexport function isGherkinStepError(value: unknown): value is GherkinStepError {\n return value instanceof GherkinStepError;\n}\n\ninterface ErrorWithCause extends Error {\n readonly cause?: unknown;\n}\n\nexport function getGherkinErrorContext(value: unknown): GherkinErrorContext | undefined {\n const visited = new Set<Error>();\n let current: unknown = value;\n\n while (current instanceof Error && !visited.has(current)) {\n visited.add(current);\n const context = getContext(current);\n if (context) {\n return context;\n }\n\n if (!(\"cause\" in current)) {\n break;\n }\n\n const cause = (current as ErrorWithCause).cause;\n if (!(cause instanceof Error)) {\n break;\n }\n current = cause;\n }\n\n return undefined;\n}\n","export interface FormatErrorCausesOptions {\n readonly includeStack?: boolean;\n readonly describeValue?: (value: unknown) => string;\n readonly maxDepth?: number;\n}\n\nexport interface FormatErrorTreeOptions extends FormatErrorCausesOptions {\n /**\n * Text used to indent nested causes. Defaults to two spaces.\n */\n readonly indent?: string;\n /**\n * Bullet prefix rendered before each error/value. Defaults to `•`.\n */\n readonly bullet?: string;\n}\n\nexport interface PrintErrorTreeOptions extends FormatErrorTreeOptions {\n readonly writer?: (line: string) => void;\n}\n\ninterface ErrorWithCause extends Error {\n readonly cause?: unknown;\n}\n\ninterface ErrorChainEntryError {\n readonly kind: \"error\";\n readonly error: Error;\n readonly depth: number;\n}\n\ninterface ErrorChainEntryValue {\n readonly kind: \"value\";\n readonly value: string;\n readonly depth: number;\n}\n\ninterface ErrorChainEntryNotice {\n readonly kind: \"notice\";\n readonly message: string;\n readonly depth: number;\n}\n\ntype ErrorChainEntry =\n | ErrorChainEntryError\n | ErrorChainEntryValue\n | ErrorChainEntryNotice;\n\nfunction hasCause(error: Error): error is ErrorWithCause {\n return \"cause\" in error;\n}\n\nfunction formatError(error: Error, includeStack: boolean): string {\n const header = `${error.name}: ${error.message}`;\n if (!includeStack) {\n return header;\n }\n const stack = error.stack ?? \"<no stack trace available>\";\n return `${header}\\nStacktrace:\\n${stack}`;\n}\n\nfunction describeUnknown(value: unknown): string {\n if (value instanceof Error) {\n return `${value.name}: ${value.message}`;\n }\n if (typeof value === \"string\") {\n return value;\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction buildErrorChain(\n root: Error,\n describeValue: (value: unknown) => string,\n maxDepth: number\n): ErrorChainEntry[] {\n const entries: ErrorChainEntry[] = [];\n const visited = new Set<Error>();\n\n let current: ErrorWithCause | undefined = root;\n let depth = 0;\n\n while (current) {\n entries.push({ kind: \"error\", error: current, depth });\n\n if (depth >= maxDepth) {\n if (hasCause(current) && current.cause !== undefined) {\n entries.push({\n kind: \"notice\",\n message: \"[max depth reached]\",\n depth: depth + 1,\n });\n }\n break;\n }\n\n visited.add(current);\n\n if (!hasCause(current) || current.cause === undefined) {\n break;\n }\n\n const cause: unknown = current.cause;\n if (!(cause instanceof Error)) {\n entries.push({\n kind: \"value\",\n value: describeValue(cause),\n depth: depth + 1,\n });\n break;\n }\n\n if (visited.has(cause)) {\n entries.push({\n kind: \"notice\",\n message: \"[cycle detected in error causes]\",\n depth: depth + 1,\n });\n break;\n }\n\n current = cause;\n depth += 1;\n }\n\n return entries;\n}\n\n/**\n * Produce a multi-line description summarising the error and its causes.\n */\nexport function formatErrorCauses(error: Error, options: FormatErrorCausesOptions = {}): string {\n const {\n includeStack = true,\n describeValue = describeUnknown,\n maxDepth = Number.POSITIVE_INFINITY,\n } = options;\n\n const entries = buildErrorChain(error, describeValue, maxDepth);\n const segments = entries.map((entry) => {\n if (entry.kind === \"error\") {\n return formatError(entry.error, includeStack);\n }\n return entry.kind === \"value\" ? entry.value : entry.message;\n });\n\n return segments.join(\"\\nCause:\\n\");\n}\n\n/**\n * Render the error cause chain as an indented tree, suitable for logging.\n */\nexport function formatErrorTree(error: Error, options: FormatErrorTreeOptions = {}): string {\n const {\n includeStack = true,\n describeValue = describeUnknown,\n maxDepth = Number.POSITIVE_INFINITY,\n indent = \" \",\n bullet = \"•\",\n } = options;\n\n const entries = buildErrorChain(error, describeValue, maxDepth);\n const lines: string[] = [];\n\n for (const entry of entries) {\n const content =\n entry.kind === \"error\"\n ? formatError(entry.error, includeStack)\n : entry.kind === \"value\"\n ? entry.value\n : entry.message;\n\n appendIndentedContent(lines, content, entry.depth, indent, bullet);\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function printErrorTree(error: Error, options: PrintErrorTreeOptions = {}): void {\n const { writer = (line: string) => console.error(line), ...rest } = options;\n const formatted = formatErrorTree(error, rest);\n for (const line of formatted.split(\"\\n\")) {\n writer(line);\n }\n}\n\nfunction appendIndentedContent(\n lines: string[],\n content: string,\n depth: number,\n indent: string,\n bullet: string\n) {\n const padding = indent.repeat(depth);\n const parts = content.split(\"\\n\");\n lines.push(`${padding}${bullet} ${parts[0]}`);\n for (let index = 1; index < parts.length; index += 1) {\n lines.push(`${padding}${indent}${parts[index]}`);\n }\n}\n","import { AutomationError, type AutomationErrorOptions } from \"./automation-error\";\n\ntype AutomationErrorConstructor<TError extends Error> = new (\n message: string,\n options?: AutomationErrorOptions\n) => TError;\n\nexport interface RaiseOptions<TError extends Error = AutomationError> extends AutomationErrorOptions {\n readonly type?: AutomationErrorConstructor<TError> | (new (message: string) => TError);\n}\n\nfunction assignCause(instance: Error, cause: unknown): void {\n Object.defineProperty(instance, \"cause\", {\n configurable: true,\n enumerable: false,\n writable: false,\n value: cause,\n });\n}\n\nfunction supportsCauseSignature<TError extends Error>(ctor: AutomationErrorConstructor<TError>): boolean {\n try {\n // eslint-disable-next-line no-new\n new ctor(\"probe\", { cause: undefined });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction buildError<TError extends Error>(\n type: AutomationErrorConstructor<TError> | (new (message: string) => TError),\n message: string,\n options: AutomationErrorOptions\n): TError {\n if (supportsCauseSignature(type as AutomationErrorConstructor<TError>)) {\n return new (type as AutomationErrorConstructor<TError>)(message, options);\n }\n\n const instance = new type(message);\n if (options.cause !== undefined) {\n assignCause(instance, options.cause);\n }\n return instance;\n}\n\n/**\n * Construct and throw an {@link AutomationError} (or custom error) with the provided message.\n */\nexport function raise<TError extends Error = AutomationError>(\n message: string,\n options: RaiseOptions<TError> = {}\n): never {\n const { type, cause } = options;\n const automationOptions: AutomationErrorOptions = cause === undefined ? {} : { cause };\n\n const error = type ? buildError(type, message, automationOptions) : new AutomationError(message, automationOptions);\n throw error;\n}\n","import { AutomationError } from \"./automation-error\";\n\nexport interface SafeOk<T> {\n readonly ok: true;\n readonly value: T;\n}\n\nexport interface SafeErr {\n readonly ok: false;\n readonly error: AutomationError;\n}\n\nexport type SafeResult<T> = SafeOk<T> | SafeErr;\n\n/**\n * Execute the callback and capture any thrown error as an {@link AutomationError}.\n */\nexport function safe<TArgs extends unknown[], TResult>(\n action: (...args: TArgs) => TResult,\n ...args: TArgs\n): SafeResult<TResult> {\n try {\n return { ok: true, value: action(...args) };\n } catch (error) {\n return { ok: false, error: AutomationError.wrap(error) };\n }\n}\n\n/**\n * Async variant of {@link safe}. Returns a promise that resolves with the value\n * or the captured {@link AutomationError}.\n */\nexport async function safeAsync<TArgs extends unknown[], TResult>(\n action: (...args: TArgs) => Promise<TResult> | TResult,\n ...args: TArgs\n): Promise<SafeResult<TResult>> {\n try {\n return { ok: true, value: await action(...args) };\n } catch (error) {\n return { ok: false, error: AutomationError.wrap(error) };\n }\n}\n"]} |
| import { AutomationError, type AutomationErrorOptions } from "./automation-error"; | ||
| type AutomationErrorConstructor<TError extends Error> = new (message: string, options?: AutomationErrorOptions) => TError; | ||
| export interface RaiseOptions<TError extends Error = AutomationError> extends AutomationErrorOptions { | ||
| readonly type?: AutomationErrorConstructor<TError> | (new (message: string) => TError); | ||
| } | ||
| /** | ||
| * Construct and throw an {@link AutomationError} (or custom error) with the provided message. | ||
| */ | ||
| export declare function raise<TError extends Error = AutomationError>(message: string, options?: RaiseOptions<TError>): never; | ||
| export {}; |
| import { AutomationError } from "./automation-error"; | ||
| export interface SafeOk<T> { | ||
| readonly ok: true; | ||
| readonly value: T; | ||
| } | ||
| export interface SafeErr { | ||
| readonly ok: false; | ||
| readonly error: AutomationError; | ||
| } | ||
| export type SafeResult<T> = SafeOk<T> | SafeErr; | ||
| /** | ||
| * Execute the callback and capture any thrown error as an {@link AutomationError}. | ||
| */ | ||
| export declare function safe<TArgs extends unknown[], TResult>(action: (...args: TArgs) => TResult, ...args: TArgs): SafeResult<TResult>; | ||
| /** | ||
| * Async variant of {@link safe}. Returns a promise that resolves with the value | ||
| * or the captured {@link AutomationError}. | ||
| */ | ||
| export declare function safeAsync<TArgs extends unknown[], TResult>(action: (...args: TArgs) => Promise<TResult> | TResult, ...args: TArgs): Promise<SafeResult<TResult>>; |
+5
-10
@@ -1,10 +0,5 @@ | ||
| declare class AutomationError extends Error { | ||
| opts: { | ||
| cause?: Error; | ||
| }; | ||
| constructor(message: string, opts?: { | ||
| cause?: Error; | ||
| }); | ||
| } | ||
| export { AutomationError }; | ||
| export { AutomationError, type AutomationErrorOptions, } from "./automation-error"; | ||
| export { GherkinStepError, getGherkinErrorContext, isGherkinStepError, type CodeContextSegment, type GherkinContextSegment, type GherkinContextPathSegment, type GherkinContextRole, type GherkinErrorContext, type GherkinStepStatus, type GherkinStepSummary, type GherkinStepErrorOptions, type SourceLocation, type SourcePosition, } from "./gherkin-error"; | ||
| export { formatErrorCauses, formatErrorTree, printErrorTree, type FormatErrorCausesOptions, type FormatErrorTreeOptions, type PrintErrorTreeOptions, } from "./formatter"; | ||
| export { raise, type RaiseOptions, } from "./raise"; | ||
| export { safe, safeAsync, type SafeErr, type SafeOk, type SafeResult, } from "./safe-error"; |
+310
-32
@@ -1,38 +0,316 @@ | ||
| "use strict"; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| // src/automation-error.ts | ||
| var AutomationError = class _AutomationError extends Error { | ||
| constructor(message, options = {}) { | ||
| const { cause } = options; | ||
| super(message); | ||
| this.name = "AutomationError"; | ||
| if (cause !== void 0) { | ||
| Object.defineProperty(this, "cause", { | ||
| configurable: true, | ||
| enumerable: false, | ||
| writable: false, | ||
| value: cause | ||
| }); | ||
| } | ||
| } | ||
| static isAutomationError(value) { | ||
| return value instanceof _AutomationError; | ||
| } | ||
| static wrap(value, fallbackMessage = "Unknown error") { | ||
| if (value instanceof _AutomationError) { | ||
| return value; | ||
| } | ||
| if (value instanceof Error) { | ||
| return new _AutomationError(value.message, { cause: value }); | ||
| } | ||
| if (typeof value === "string") { | ||
| return new _AutomationError(value); | ||
| } | ||
| return new _AutomationError(fallbackMessage, { cause: value }); | ||
| } | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| // src/gherkin-error.ts | ||
| var CONTEXT_SYMBOL = Symbol.for("autometa.gherkinErrorContext"); | ||
| function freezePosition(position) { | ||
| return Object.freeze({ | ||
| line: position.line, | ||
| column: position.column | ||
| }); | ||
| } | ||
| function freezeLocation(location) { | ||
| return Object.freeze({ | ||
| filePath: location.filePath, | ||
| start: freezePosition(location.start), | ||
| ...location.end ? { end: freezePosition(location.end) } : {} | ||
| }); | ||
| } | ||
| function freezeGherkinSegment(segment) { | ||
| return Object.freeze({ | ||
| location: freezeLocation(segment.location), | ||
| ...segment.featureName !== void 0 ? { featureName: segment.featureName } : {}, | ||
| ...segment.stepKeyword !== void 0 ? { stepKeyword: segment.stepKeyword } : {}, | ||
| ...segment.stepText !== void 0 ? { stepText: segment.stepText } : {} | ||
| }); | ||
| } | ||
| function freezeCodeSegment(segment) { | ||
| return Object.freeze({ | ||
| location: freezeLocation(segment.location), | ||
| ...segment.functionName !== void 0 ? { functionName: segment.functionName } : {} | ||
| }); | ||
| } | ||
| function freezePathSegment(segment) { | ||
| return Object.freeze({ | ||
| role: segment.role, | ||
| location: freezeLocation(segment.location), | ||
| ...segment.keyword !== void 0 ? { keyword: segment.keyword } : {}, | ||
| ...segment.name !== void 0 ? { name: segment.name } : {}, | ||
| ...segment.text !== void 0 ? { text: segment.text } : {}, | ||
| ...segment.index !== void 0 ? { index: segment.index } : {} | ||
| }); | ||
| } | ||
| function freezePath(path) { | ||
| return Object.freeze(path.map((segment) => freezePathSegment(segment))); | ||
| } | ||
| function freezeStepSummary(step) { | ||
| return Object.freeze({ | ||
| status: step.status, | ||
| ...step.keyword !== void 0 ? { keyword: step.keyword } : {}, | ||
| ...step.text !== void 0 ? { text: step.text } : {}, | ||
| ...step.location ? { location: freezeLocation(step.location) } : {} | ||
| }); | ||
| } | ||
| function freezeSteps(steps) { | ||
| return Object.freeze(steps.map((step) => freezeStepSummary(step))); | ||
| } | ||
| function freezeContext(context) { | ||
| return Object.freeze({ | ||
| ...context.gherkin ? { gherkin: freezeGherkinSegment(context.gherkin) } : {}, | ||
| ...context.code ? { code: freezeCodeSegment(context.code) } : {}, | ||
| ...context.path ? { path: freezePath(context.path) } : {}, | ||
| ...context.steps ? { steps: freezeSteps(context.steps) } : {} | ||
| }); | ||
| } | ||
| function setContext(target, context) { | ||
| Object.defineProperty(target, CONTEXT_SYMBOL, { | ||
| configurable: false, | ||
| enumerable: false, | ||
| writable: false, | ||
| value: freezeContext(context) | ||
| }); | ||
| } | ||
| function getContext(target) { | ||
| if (!target || typeof target !== "object") { | ||
| return void 0; | ||
| } | ||
| return to; | ||
| return Reflect.get(target, CONTEXT_SYMBOL); | ||
| } | ||
| var GherkinStepError = class extends AutomationError { | ||
| constructor(message, options) { | ||
| const { context, ...rest } = options; | ||
| super(message, rest); | ||
| this.name = "GherkinStepError"; | ||
| setContext(this, context); | ||
| } | ||
| get context() { | ||
| const context = getContext(this); | ||
| if (!context) { | ||
| throw new Error("Missing Gherkin context for error instance"); | ||
| } | ||
| return context; | ||
| } | ||
| }; | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| function isGherkinStepError(value) { | ||
| return value instanceof GherkinStepError; | ||
| } | ||
| function getGherkinErrorContext(value) { | ||
| const visited = /* @__PURE__ */ new Set(); | ||
| let current = value; | ||
| while (current instanceof Error && !visited.has(current)) { | ||
| visited.add(current); | ||
| const context = getContext(current); | ||
| if (context) { | ||
| return context; | ||
| } | ||
| if (!("cause" in current)) { | ||
| break; | ||
| } | ||
| const cause = current.cause; | ||
| if (!(cause instanceof Error)) { | ||
| break; | ||
| } | ||
| current = cause; | ||
| } | ||
| return void 0; | ||
| } | ||
| // src/index.ts | ||
| var src_exports = {}; | ||
| __export(src_exports, { | ||
| AutomationError: () => AutomationError | ||
| }); | ||
| module.exports = __toCommonJS(src_exports); | ||
| // src/formatter.ts | ||
| function hasCause(error) { | ||
| return "cause" in error; | ||
| } | ||
| function formatError(error, includeStack) { | ||
| const header = `${error.name}: ${error.message}`; | ||
| if (!includeStack) { | ||
| return header; | ||
| } | ||
| const stack = error.stack ?? "<no stack trace available>"; | ||
| return `${header} | ||
| Stacktrace: | ||
| ${stack}`; | ||
| } | ||
| function describeUnknown(value) { | ||
| if (value instanceof Error) { | ||
| return `${value.name}: ${value.message}`; | ||
| } | ||
| if (typeof value === "string") { | ||
| return value; | ||
| } | ||
| try { | ||
| return JSON.stringify(value); | ||
| } catch { | ||
| return String(value); | ||
| } | ||
| } | ||
| function buildErrorChain(root, describeValue, maxDepth) { | ||
| const entries = []; | ||
| const visited = /* @__PURE__ */ new Set(); | ||
| let current = root; | ||
| let depth = 0; | ||
| while (current) { | ||
| entries.push({ kind: "error", error: current, depth }); | ||
| if (depth >= maxDepth) { | ||
| if (hasCause(current) && current.cause !== void 0) { | ||
| entries.push({ | ||
| kind: "notice", | ||
| message: "[max depth reached]", | ||
| depth: depth + 1 | ||
| }); | ||
| } | ||
| break; | ||
| } | ||
| visited.add(current); | ||
| if (!hasCause(current) || current.cause === void 0) { | ||
| break; | ||
| } | ||
| const cause = current.cause; | ||
| if (!(cause instanceof Error)) { | ||
| entries.push({ | ||
| kind: "value", | ||
| value: describeValue(cause), | ||
| depth: depth + 1 | ||
| }); | ||
| break; | ||
| } | ||
| if (visited.has(cause)) { | ||
| entries.push({ | ||
| kind: "notice", | ||
| message: "[cycle detected in error causes]", | ||
| depth: depth + 1 | ||
| }); | ||
| break; | ||
| } | ||
| current = cause; | ||
| depth += 1; | ||
| } | ||
| return entries; | ||
| } | ||
| function formatErrorCauses(error, options = {}) { | ||
| const { | ||
| includeStack = true, | ||
| describeValue = describeUnknown, | ||
| maxDepth = Number.POSITIVE_INFINITY | ||
| } = options; | ||
| const entries = buildErrorChain(error, describeValue, maxDepth); | ||
| const segments = entries.map((entry) => { | ||
| if (entry.kind === "error") { | ||
| return formatError(entry.error, includeStack); | ||
| } | ||
| return entry.kind === "value" ? entry.value : entry.message; | ||
| }); | ||
| return segments.join("\nCause:\n"); | ||
| } | ||
| function formatErrorTree(error, options = {}) { | ||
| const { | ||
| includeStack = true, | ||
| describeValue = describeUnknown, | ||
| maxDepth = Number.POSITIVE_INFINITY, | ||
| indent = " ", | ||
| bullet = "\u2022" | ||
| } = options; | ||
| const entries = buildErrorChain(error, describeValue, maxDepth); | ||
| const lines = []; | ||
| for (const entry of entries) { | ||
| const content = entry.kind === "error" ? formatError(entry.error, includeStack) : entry.kind === "value" ? entry.value : entry.message; | ||
| appendIndentedContent(lines, content, entry.depth, indent, bullet); | ||
| } | ||
| return lines.join("\n"); | ||
| } | ||
| function printErrorTree(error, options = {}) { | ||
| const { writer = (line) => console.error(line), ...rest } = options; | ||
| const formatted = formatErrorTree(error, rest); | ||
| for (const line of formatted.split("\n")) { | ||
| writer(line); | ||
| } | ||
| } | ||
| function appendIndentedContent(lines, content, depth, indent, bullet) { | ||
| const padding = indent.repeat(depth); | ||
| const parts = content.split("\n"); | ||
| lines.push(`${padding}${bullet} ${parts[0]}`); | ||
| for (let index = 1; index < parts.length; index += 1) { | ||
| lines.push(`${padding}${indent}${parts[index]}`); | ||
| } | ||
| } | ||
| // src/automation-error.ts | ||
| var AutomationError = class extends Error { | ||
| constructor(message, opts = {}) { | ||
| super(message); | ||
| this.opts = opts; | ||
| this.name = "AutomationError"; | ||
| // src/raise.ts | ||
| function assignCause(instance, cause) { | ||
| Object.defineProperty(instance, "cause", { | ||
| configurable: true, | ||
| enumerable: false, | ||
| writable: false, | ||
| value: cause | ||
| }); | ||
| } | ||
| function supportsCauseSignature(ctor) { | ||
| try { | ||
| new ctor("probe", { cause: void 0 }); | ||
| return true; | ||
| } catch { | ||
| return false; | ||
| } | ||
| }; | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| AutomationError | ||
| }); | ||
| } | ||
| function buildError(type, message, options) { | ||
| if (supportsCauseSignature(type)) { | ||
| return new type(message, options); | ||
| } | ||
| const instance = new type(message); | ||
| if (options.cause !== void 0) { | ||
| assignCause(instance, options.cause); | ||
| } | ||
| return instance; | ||
| } | ||
| function raise(message, options = {}) { | ||
| const { type, cause } = options; | ||
| const automationOptions = cause === void 0 ? {} : { cause }; | ||
| const error = type ? buildError(type, message, automationOptions) : new AutomationError(message, automationOptions); | ||
| throw error; | ||
| } | ||
| // src/safe-error.ts | ||
| function safe(action, ...args) { | ||
| try { | ||
| return { ok: true, value: action(...args) }; | ||
| } catch (error) { | ||
| return { ok: false, error: AutomationError.wrap(error) }; | ||
| } | ||
| } | ||
| async function safeAsync(action, ...args) { | ||
| try { | ||
| return { ok: true, value: await action(...args) }; | ||
| } catch (error) { | ||
| return { ok: false, error: AutomationError.wrap(error) }; | ||
| } | ||
| } | ||
| export { AutomationError, GherkinStepError, formatErrorCauses, formatErrorTree, getGherkinErrorContext, isGherkinStepError, printErrorTree, raise, safe, safeAsync }; | ||
| //# sourceMappingURL=out.js.map | ||
| //# sourceMappingURL=index.js.map |
+38
-20
| { | ||
| "name": "@autometa/errors", | ||
| "version": "0.3.1", | ||
| "main": "dist/index.js", | ||
| "module": "dist/esm/index.js", | ||
| "version": "1.0.0-rc.0", | ||
| "description": "Error utilities for Autometa runtimes.", | ||
| "type": "module", | ||
| "main": "dist/index.cjs", | ||
| "module": "dist/index.js", | ||
| "types": "dist/index.d.ts", | ||
| "type": "module", | ||
| "typesVersions": { | ||
| "*": { | ||
| "*": [ | ||
| "src/index.ts" | ||
| ] | ||
| } | ||
| }, | ||
| "files": [ | ||
| "dist" | ||
| ], | ||
| "exports": { | ||
| "import": "./dist/esm/index.js", | ||
| "require": "./dist/index.js", | ||
| "default": "./dist/esm/index.js", | ||
| "import": "./dist/index.js", | ||
| "require": "./dist/index.cjs", | ||
| "default": "./dist/index.js", | ||
| "types": "./dist/index.d.ts" | ||
| }, | ||
| "author": "Ben Aherne", | ||
| "license": "MIT", | ||
| "devDependencies": { | ||
| "@autometa/types": "0.3.1", | ||
| "@types/node": "^18.11.18", | ||
| "@typescript-eslint/eslint-plugin": "^5.54.1", | ||
| "@typescript-eslint/parser": "^5.54.1", | ||
| "eslint": "^8.44.0", | ||
| "eslint-config-custom": "0.5.1", | ||
| "prettier": "^2.8.3", | ||
| "eslint": "^8.37.0", | ||
| "eslint-config-prettier": "^8.3.0", | ||
| "rimraf": "^4.1.2", | ||
| "tsconfig": " *", | ||
| "tsup": "^6.7.0", | ||
| "tsup": "^7.2.0", | ||
| "typescript": "^4.9.5", | ||
| "vitest": "^0.29.8" | ||
| "vitest": "1.4.0", | ||
| "tsconfig": "0.7.0", | ||
| "eslint-config-custom": "0.6.0", | ||
| "tsup-config": "0.1.0" | ||
| }, | ||
| "scripts": { | ||
| "prettify": "prettier --config .prettierrc 'src/**/*.ts' --write", | ||
| "type-check": "tsc --noEmit -p tsconfig.dev.json", | ||
| "type-check:watch": "tsc --noEmit --watch -p tsconfig.dev.json", | ||
| "build": "tsup && pnpm run build:types", | ||
| "build:types": "rimraf tsconfig.types.tsbuildinfo && tsc --build tsconfig.types.json", | ||
| "build:watch": "tsup --watch", | ||
| "dev": "tsup --watch", | ||
| "test": "vitest run --passWithNoTests", | ||
| "test:watch": "vitest --passWithNoTests", | ||
| "test:ui": "vitest --ui --passWithNoTests", | ||
| "coverage": "vitest run --coverage --passWithNoTests", | ||
| "lint": "eslint . --max-warnings 0", | ||
| "lint:fix": "eslint . --fix", | ||
| "clean": "rimraf dist", | ||
| "build": "tsup" | ||
| }, | ||
| "readme": "# Errors\n\nErrors & Exceptions implementation for @autometa.\n" | ||
| "prettify": "prettier --config .prettierrc 'src/**/*.ts' --write", | ||
| "clean": "rimraf dist" | ||
| } | ||
| } |
+46
-2
@@ -1,3 +0,47 @@ | ||
| # Errors | ||
| # @autometa/errors | ||
| Errors & Exceptions implementation for @autometa. | ||
| Robust error primitives used across the Autometa ecosystem. | ||
| ## Installation | ||
| ```bash | ||
| pnpm add @autometa/errors | ||
| ``` | ||
| ## Usage | ||
| ```ts | ||
| import { | ||
| AutomationError, | ||
| formatErrorCauses, | ||
| formatErrorTree, | ||
| printErrorTree, | ||
| raise, | ||
| safe, | ||
| safeAsync, | ||
| } from "@autometa/errors"; | ||
| function loadConfig(path: string) { | ||
| const result = safe(() => readFileSync(path, "utf8")); | ||
| if (!result.ok) { | ||
| raise("Failed to load configuration", { cause: result.error }); | ||
| } | ||
| return result.value; | ||
| } | ||
| try { | ||
| loadConfig("./app.json"); | ||
| } catch (error) { | ||
| const automation = AutomationError.wrap(error); | ||
| console.error(formatErrorCauses(automation, { includeStack: false })); | ||
| printErrorTree(automation, { includeStack: false }); | ||
| } | ||
| ``` | ||
| ## API highlights | ||
| - `AutomationError` – first-class error base with helpers to detect (`isAutomationError`) and wrap unknown values (`wrap`). | ||
| - `raise` – construct and throw `AutomationError` or custom subclasses (legacy constructors supported) with optional nested causes. | ||
| - `safe`/`safeAsync` – execute functions, capturing failures as `AutomationError` instances while returning a discriminated union result. | ||
| - `formatErrorCauses` – produce readable multi-line descriptions of error chains with configurable stack inclusion and depth limits. | ||
| - `formatErrorTree` / `printErrorTree` – pretty-print error causes as an indented tree, ideal for console or structured logs. |
Sorry, the diff of this file is not supported yet
| module.exports = { | ||
| root: true, | ||
| extends: ["custom"], | ||
| }; |
| > @autometa/errors@0.3.1 build /home/runner/work/autometa/autometa/packages/errors | ||
| > tsup | ||
| [34mCLI[39m Building entry: src/index.ts | ||
| [34mCLI[39m Using tsconfig: tsconfig.json | ||
| [34mCLI[39m tsup v6.7.0 | ||
| [34mCLI[39m Using tsup config: /home/runner/work/autometa/autometa/packages/errors/tsup.config.ts | ||
| [34mCLI[39m Target: es2020 | ||
| [34mCLI[39m Cleaning output folder | ||
| [34mCJS[39m Build start | ||
| [34mESM[39m Build start | ||
| [33mCJS[39m [33mYou have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin[39m | ||
| [33mESM[39m [33mYou have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin[39m | ||
| [32mCJS[39m [1mdist/index.js [22m[32m1.22 KB[39m | ||
| [32mCJS[39m ⚡️ Build success in 104ms | ||
| [32mESM[39m [1mdist/esm/index.js [22m[32m221.00 B[39m | ||
| [32mESM[39m ⚡️ Build success in 104ms | ||
| [34mDTS[39m Build start | ||
| [32mDTS[39m ⚡️ Build success in 20668ms | ||
| [32mDTS[39m [1mdist/index.d.ts [22m[32m192.00 B[39m |
-25
| # Gherkin | ||
| ## 0.3.1 | ||
| ### Patch Changes | ||
| - 6a4a9ac: Swapped project type to "composite", unified build system for most projects | ||
| ## 0.3.0 | ||
| ### Minor Changes | ||
| - b48f577: Added initial implemention of scopes and updated `overloads` | ||
| ## 0.2.1 | ||
| ### Patch Changes | ||
| - cfc35f4: Update build systems on packages to use tsup | ||
| ## 0.2.0 | ||
| ### Minor Changes | ||
| - 0a27508: Created "gherkin" package to help split up cucumber-runner |
| // src/automation-error.ts | ||
| var AutomationError = class extends Error { | ||
| constructor(message, opts = {}) { | ||
| super(message); | ||
| this.opts = opts; | ||
| this.name = "AutomationError"; | ||
| } | ||
| }; | ||
| export { | ||
| AutomationError | ||
| }; |
| import { defineConfig } from "tsup"; | ||
| export default defineConfig({ | ||
| clean: true, // clean up the dist folder | ||
| dts: true, // generate dts files | ||
| format: ["cjs", "esm"], // generate cjs and esm files | ||
| skipNodeModulesBundle: true, | ||
| entryPoints: ["src/index.ts"], | ||
| target: "es2020", | ||
| outDir: "dist", | ||
| legacyOutput: true, | ||
| external: ["dist"], | ||
| }); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
74147
1205.18%13
18.18%758
952.78%47
1075%2
100%1
Infinity%