@autometa/errors
Advanced tools
@@ -1,1 +0,1 @@ | ||
| {"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 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"]} |
@@ -1,1 +0,1 @@ | ||
| {"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 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"]} |
+3
-3
| { | ||
| "name": "@autometa/errors", | ||
| "version": "1.0.0-rc.1", | ||
| "version": "1.0.0-rc.2", | ||
| "description": "Error utilities for Autometa runtimes.", | ||
@@ -37,4 +37,4 @@ "type": "module", | ||
| "eslint-config-custom": "0.6.0", | ||
| "tsconfig": "0.7.0", | ||
| "tsup-config": "0.1.0" | ||
| "tsup-config": "0.1.0", | ||
| "tsconfig": "0.7.0" | ||
| }, | ||
@@ -41,0 +41,0 @@ "scripts": { |
74131
-0.02%