Skip to content

Commit ab0e958

Browse files
committed
imp: clear place for errors
1 parent f7688b6 commit ab0e958

4 files changed

Lines changed: 57 additions & 28 deletions

File tree

src/errors/PipelineError.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
export class PipelineError<T = unknown> extends Error {
2+
public readonly name = "PipelineError";
3+
4+
/** The function that caused the error in the pipeline. */
5+
public readonly fn: Function;
6+
7+
/** The value of `this`` when the error occurred. */
8+
public readonly thisValue: unknown;
9+
10+
/** The input that was provided to the function that caused the error. */
11+
public readonly input: T;
12+
13+
constructor({
14+
fn,
15+
input,
16+
thisValue,
17+
cause,
18+
}: {
19+
fn: Function;
20+
input: T;
21+
thisValue: unknown;
22+
cause: unknown;
23+
}) {
24+
const message = cause instanceof Error ? cause.message : String(cause);
25+
26+
super(`Pipeline step failed: ${message}`, { cause });
27+
28+
this.fn = fn;
29+
this.input = input;
30+
this.cause = cause;
31+
32+
if (cause instanceof Error) {
33+
this.stack = cause.stack;
34+
}
35+
}
36+
}

src/functions/pipe.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { PipelineError } from "~/errors/PipelineError";
2+
13
export type TransformFn<This, In, Out> =
24
| ((this: This, value: In) => Out)
35
| ((value: In) => Out);
@@ -88,7 +90,16 @@ export function pipe(this: any, ...fns: PipeEntry<any, any, any>[]) {
8890
fn = entry;
8991
}
9092

91-
return fn.call(this, carry);
93+
try {
94+
return fn.call(this, carry);
95+
} catch (error) {
96+
throw new PipelineError({
97+
fn,
98+
input: carry,
99+
thisValue: this,
100+
cause: error,
101+
});
102+
}
92103
}, initialValue);
93104
};
94105
}

src/functions/pipeAsync.ts

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { PipelineError } from "~/errors/PipelineError";
12
import type { PipeCondition } from "./pipe";
23

34
export type AsyncTransformFn<This, In, Out> =
@@ -90,35 +91,15 @@ export function pipeAsync(this: any, ...fns: AsyncPipeEntry<any, any, any>[]) {
9091
try {
9192
carry = await fn.call(this, carry);
9293
} catch (error) {
93-
throw new PipelineError(fn, error);
94+
throw new PipelineError({
95+
fn,
96+
input: carry,
97+
thisValue: this,
98+
cause: error,
99+
});
94100
}
95101
}
96102

97103
return carry;
98104
};
99105
}
100-
101-
/**
102-
* Is thrown when an error occurs within a piped function.
103-
* It wraps the original error and exposes the function that caused the error.
104-
*/
105-
export class PipelineError extends Error {
106-
constructor(
107-
public readonly functionThatFailed: Function,
108-
originalError: unknown
109-
) {
110-
const message = `An error occurred in a piped function: ${
111-
originalError instanceof Error
112-
? originalError.message
113-
: String(originalError)
114-
}`;
115-
116-
super(message);
117-
118-
this.name = "PipelineError";
119-
120-
if (originalError instanceof Error && originalError.stack) {
121-
this.stack = originalError.stack;
122-
}
123-
}
124-
}

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ export {
4545
} from "~/functions/pipe.js";
4646
export {
4747
pipeAsync,
48-
PipelineError,
4948
type AsyncPipeEntry,
5049
type AsyncTransformFn,
5150
} from "~/functions/pipeAsync.js";
@@ -59,3 +58,5 @@ export { tap } from "~/functions/tap.js";
5958
export { throttle } from "~/functions/throttle.js";
6059
export { value, type Value } from "~/functions/value.js";
6160
export { when } from "~/functions/when.js";
61+
62+
export { PipelineError } from "~/errors/PipelineError.js";

0 commit comments

Comments
 (0)