-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathresult.ts
More file actions
71 lines (58 loc) · 1.81 KB
/
result.ts
File metadata and controls
71 lines (58 loc) · 1.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Adapting Rust's Result<T, E> construct for
// a robust error handling system
// Error is a serializable (Jsonable) object
// see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#description
export type Jsonable =
| string
| number
| boolean
| null
| undefined
| readonly Jsonable[]
| { readonly [key: string]: Jsonable }
| { toJSON(): Jsonable };
// base error class to separate message from metadata
export class BaseError extends Error {
public context?: Jsonable;
constructor(
message: string,
options: { error?: Error; context?: Jsonable } = {},
) {
const { error, context } = options;
super(message, { cause: error });
this.name = this.constructor.name;
this.context = context;
}
withContext(ctx: Jsonable): this {
this.context = ctx;
return this;
}
}
export type Success<T> = { success: true; result: T };
export type Failure<E extends BaseError> = { success: false; result: E };
export type Result<T, E extends BaseError> = Success<T> | Failure<E>;
//---------- UTILS ----------
// wrap a value in Success<T>
export function ok<T>(value: T): Success<T> {
return { success: true, result: value };
}
// wrap an error in Failure<E>
export function err<E extends BaseError>(value: E): Failure<E> {
return { success: false, result: value };
}
// extract result value with no care if it's
// success or failure
export function unwrap<T, E extends BaseError>(result: Result<T, E>) {
return result.result;
}
// either extract result value if it's a success
// or rethrow the underlying error
//
// used for propagating / hoisting errors to the next handler
export function unwrapOrThrow<T, E extends BaseError>(result: Result<T, E>): T {
if (result.success == true) {
return result.result;
} else {
throw result.result;
}
}