🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@autometa/errors

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@autometa/errors - npm Package Compare versions

Comparing version
0.3.1
to
1.0.0-rc.0
+12
dist/automation-error.d.ts
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;
'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";

@@ -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
{
"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"
}
}

@@ -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
CLI Building entry: src/index.ts
CLI Using tsconfig: tsconfig.json
CLI tsup v6.7.0
CLI Using tsup config: /home/runner/work/autometa/autometa/packages/errors/tsup.config.ts
CLI Target: es2020
CLI Cleaning output folder
CJS Build start
ESM Build start
CJS You have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin
ESM You have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin
CJS dist/index.js 1.22 KB
CJS ⚡️ Build success in 104ms
ESM dist/esm/index.js 221.00 B
ESM ⚡️ Build success in 104ms
DTS Build start
DTS ⚡️ Build success in 20668ms
DTS dist/index.d.ts 192.00 B
# 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"],
});