zresult 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/LICENSE +20 -0
- package/README.md +218 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +101 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +9 -0
- package/dist/index.test.js +271 -0
- package/dist/index.test.js.map +1 -0
- package/package.json +149 -0
- package/src/index.test.ts +336 -0
- package/src/index.ts +157 -0
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
Copyright © 2017 Nicolas Froidure
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the “Software”), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in
|
|
12
|
+
all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
20
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
[//]: # ( )
|
|
2
|
+
[//]: # (This file is automatically generated by a `metapak`)
|
|
3
|
+
[//]: # (module. Do not change it except between the)
|
|
4
|
+
[//]: # (`content:start/end` flags, your changes would)
|
|
5
|
+
[//]: # (be overridden.)
|
|
6
|
+
[//]: # ( )
|
|
7
|
+
# zresult
|
|
8
|
+
> It helps to know the error you'll get.
|
|
9
|
+
|
|
10
|
+
[](https://github.com/nfroidure/zresult/blob/main/LICENSE)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
[//]: # (::contents:start)
|
|
14
|
+
|
|
15
|
+
`zresult` is an ultra-lightweight TypeScript wrapper designed to transform error
|
|
16
|
+
handling into a predictable, strictly typed, and elegant data flow. Inspired by
|
|
17
|
+
the `Result` pattern from Rust and Go, it integrates natively with `yerror` to
|
|
18
|
+
provide absolute **Type Safety** for your error codes.
|
|
19
|
+
|
|
20
|
+
## Key Features
|
|
21
|
+
|
|
22
|
+
- ✅ **No more noisy `try/catch`**: Handle errors as return values.
|
|
23
|
+
- ✅ **Exhaustive Type Safety**: Your error codes and debug data are validated
|
|
24
|
+
via the [yerror](https://www.npmjs.com/package/yerror)'s `YErrorRegistry`
|
|
25
|
+
type.
|
|
26
|
+
- ✅ **Explicit Flow**: Clear distinction between synchronous and asynchronous
|
|
27
|
+
operations.
|
|
28
|
+
- ✅ **Selective Catching**: Capture only the errors you know how to handle, let
|
|
29
|
+
the others bubble up (e.g., unexpected bugs or `ReferenceError`).
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install zresult yerror
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### 1. Creating Success or Failure
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { ok, fail } from 'zresult';
|
|
43
|
+
|
|
44
|
+
const success = ok(42);
|
|
45
|
+
// returns { ok: true, value: 42 }
|
|
46
|
+
|
|
47
|
+
const failure = fail('E_USER_NOT_FOUND', ['123']);
|
|
48
|
+
// returns { ok: false, error: YError }
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2. Executing a Function (Attempt)
|
|
52
|
+
|
|
53
|
+
Use attempt for asynchronous functions and attemptSync for the synchronous
|
|
54
|
+
world.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { attempt, attemptSync } from 'zresult';
|
|
58
|
+
|
|
59
|
+
// Asynchronous
|
|
60
|
+
const result = await attempt(fetchUser, userId);
|
|
61
|
+
|
|
62
|
+
if (!result.ok) {
|
|
63
|
+
console.error(result.error.code); // Strictly typed!
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log(result.value.name);
|
|
67
|
+
|
|
68
|
+
// Synchronous
|
|
69
|
+
const config = attemptSync(parseConfig, rawData);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 3. Selective Capture (The "From" Pattern)
|
|
73
|
+
|
|
74
|
+
Only handle expected errors and let unexpected bugs crash the process cleanly.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { attemptFrom } from 'zresult';
|
|
78
|
+
|
|
79
|
+
// We only capture 'E_NETWORK' errors
|
|
80
|
+
const result = await attemptFrom(['E_NETWORK'], sendMessage, msg);
|
|
81
|
+
|
|
82
|
+
if (!result.ok) {
|
|
83
|
+
// result.error is strictly typed as YError<'E_NETWORK'> here
|
|
84
|
+
return retry(msg);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 4. Stabilizing an existing Promise (Settle)
|
|
89
|
+
|
|
90
|
+
Useful for transforming a Promise from a third-party library into a Result.
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { settle } from 'zresult';
|
|
94
|
+
|
|
95
|
+
const result = await settle(externalApi.call());
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Integration with YError
|
|
99
|
+
|
|
100
|
+
`zresult` shines when used with a declared `YErrorRegistry`. TypeScript will
|
|
101
|
+
prevent you from using non-existent error codes or invalid debug arguments.
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
declare module 'yerror' {
|
|
105
|
+
interface YErrorRegistry {
|
|
106
|
+
E_ACCESS_DENIED: [userId: string];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// TypeScript validates both 'E_ACCESS_DENIED' and the debug array contents
|
|
111
|
+
return fail('E_ACCESS_DENIED', ['user_123']);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
[//]: # (::contents:end)
|
|
115
|
+
|
|
116
|
+
# API
|
|
117
|
+
## Functions
|
|
118
|
+
|
|
119
|
+
<dl>
|
|
120
|
+
<dt><a href="#ok">ok()</a></dt>
|
|
121
|
+
<dd><p>Create a successful result</p>
|
|
122
|
+
</dd>
|
|
123
|
+
<dt><a href="#fail">fail()</a></dt>
|
|
124
|
+
<dd><p>Create a failure result using a YError code and debug values</p>
|
|
125
|
+
</dd>
|
|
126
|
+
<dt><a href="#failWith">failWith()</a></dt>
|
|
127
|
+
<dd><p>Wrap an existing error into a failure result</p>
|
|
128
|
+
</dd>
|
|
129
|
+
<dt><a href="#settle">settle()</a></dt>
|
|
130
|
+
<dd><p>Transform a Promise into a Result catching any error</p>
|
|
131
|
+
</dd>
|
|
132
|
+
<dt><a href="#settleFrom">settleFrom()</a></dt>
|
|
133
|
+
<dd><p>Transform a Promise into a Result catching only known
|
|
134
|
+
errors and letting unknown pass through</p>
|
|
135
|
+
</dd>
|
|
136
|
+
<dt><a href="#attempt">attempt()</a></dt>
|
|
137
|
+
<dd><p>Runs an asynchronous function and provides a Result catching
|
|
138
|
+
any error</p>
|
|
139
|
+
</dd>
|
|
140
|
+
<dt><a href="#attemptFrom">attemptFrom()</a></dt>
|
|
141
|
+
<dd><p>Runs an asynchronous function and provides a Result catching
|
|
142
|
+
only known errors and letting unknown pass through</p>
|
|
143
|
+
</dd>
|
|
144
|
+
<dt><a href="#attemptSync">attemptSync()</a></dt>
|
|
145
|
+
<dd><p>Runs a synchronous function and provides a Result catching
|
|
146
|
+
any error</p>
|
|
147
|
+
</dd>
|
|
148
|
+
<dt><a href="#attemptSyncFrom">attemptSyncFrom()</a></dt>
|
|
149
|
+
<dd><p>Runs a synchronous function and provides a Result catching
|
|
150
|
+
only known errors and letting unknown pass through</p>
|
|
151
|
+
</dd>
|
|
152
|
+
</dl>
|
|
153
|
+
|
|
154
|
+
<a name="ok"></a>
|
|
155
|
+
|
|
156
|
+
## ok()
|
|
157
|
+
Create a successful result
|
|
158
|
+
|
|
159
|
+
**Kind**: global function
|
|
160
|
+
<a name="fail"></a>
|
|
161
|
+
|
|
162
|
+
## fail()
|
|
163
|
+
Create a failure result using a YError code and debug values
|
|
164
|
+
|
|
165
|
+
**Kind**: global function
|
|
166
|
+
<a name="failWith"></a>
|
|
167
|
+
|
|
168
|
+
## failWith()
|
|
169
|
+
Wrap an existing error into a failure result
|
|
170
|
+
|
|
171
|
+
**Kind**: global function
|
|
172
|
+
<a name="settle"></a>
|
|
173
|
+
|
|
174
|
+
## settle()
|
|
175
|
+
Transform a Promise into a Result catching any error
|
|
176
|
+
|
|
177
|
+
**Kind**: global function
|
|
178
|
+
<a name="settleFrom"></a>
|
|
179
|
+
|
|
180
|
+
## settleFrom()
|
|
181
|
+
Transform a Promise into a Result catching only known
|
|
182
|
+
errors and letting unknown pass through
|
|
183
|
+
|
|
184
|
+
**Kind**: global function
|
|
185
|
+
<a name="attempt"></a>
|
|
186
|
+
|
|
187
|
+
## attempt()
|
|
188
|
+
Runs an asynchronous function and provides a Result catching
|
|
189
|
+
any error
|
|
190
|
+
|
|
191
|
+
**Kind**: global function
|
|
192
|
+
<a name="attemptFrom"></a>
|
|
193
|
+
|
|
194
|
+
## attemptFrom()
|
|
195
|
+
Runs an asynchronous function and provides a Result catching
|
|
196
|
+
only known errors and letting unknown pass through
|
|
197
|
+
|
|
198
|
+
**Kind**: global function
|
|
199
|
+
<a name="attemptSync"></a>
|
|
200
|
+
|
|
201
|
+
## attemptSync()
|
|
202
|
+
Runs a synchronous function and provides a Result catching
|
|
203
|
+
any error
|
|
204
|
+
|
|
205
|
+
**Kind**: global function
|
|
206
|
+
<a name="attemptSyncFrom"></a>
|
|
207
|
+
|
|
208
|
+
## attemptSyncFrom()
|
|
209
|
+
Runs a synchronous function and provides a Result catching
|
|
210
|
+
only known errors and letting unknown pass through
|
|
211
|
+
|
|
212
|
+
**Kind**: global function
|
|
213
|
+
|
|
214
|
+
# Authors
|
|
215
|
+
- [Nicolas Froidure](http://insertafter.com/en/index.html)
|
|
216
|
+
|
|
217
|
+
# License
|
|
218
|
+
[MIT](https://github.com/nfroidure/zresult/blob/main/LICENSE)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type YErrorDebug, type YErrorRegistry, YError } from 'yerror';
|
|
2
|
+
/** A type to encapsulate a result that can either be
|
|
3
|
+
* failure or a success */
|
|
4
|
+
export type Result<T, E extends Error | YError> = {
|
|
5
|
+
readonly ok: true;
|
|
6
|
+
readonly value: T;
|
|
7
|
+
} | {
|
|
8
|
+
readonly ok: false;
|
|
9
|
+
readonly error: E;
|
|
10
|
+
};
|
|
11
|
+
/** Create a successful result */
|
|
12
|
+
export declare function ok<T>(value: T): Result<T, never>;
|
|
13
|
+
/** Create a failure result using a YError code and debug values */
|
|
14
|
+
export declare function fail<C extends keyof YErrorRegistry>(code: C, debug: YErrorDebug<C>, error?: Error): Result<never, YError<C>>;
|
|
15
|
+
/** Wrap an existing error into a failure result */
|
|
16
|
+
export declare function failWith<E extends Error | YError>(error: E): Result<never, E extends YError<infer C> ? YError<C> : YError<'E_UNEXPECTED'>>;
|
|
17
|
+
/** Transform a Promise into a Result catching any error */
|
|
18
|
+
export declare function settle<T>(promise: Promise<T>): Promise<Result<T, YError>>;
|
|
19
|
+
/** Transform a Promise into a Result catching only known
|
|
20
|
+
* errors and letting unknown pass through */
|
|
21
|
+
export declare function settleFrom<C extends keyof YErrorRegistry, T>(codes: C[], promise: Promise<T>): Promise<Result<T, YError<C>>>;
|
|
22
|
+
/** Runs an asynchronous function and provides a Result catching
|
|
23
|
+
* any error */
|
|
24
|
+
export declare function attempt<T, A extends any[]>(fn: (...args: A) => Promise<T>, ...args: A): Promise<Result<T, YError>>;
|
|
25
|
+
/** Runs an asynchronous function and provides a Result catching
|
|
26
|
+
* only known errors and letting unknown pass through */
|
|
27
|
+
export declare function attemptFrom<C extends keyof YErrorRegistry, T, A extends any[]>(codes: C[], fn: (...args: A) => Promise<T>, ...args: A): Promise<Result<T, YError<C>>>;
|
|
28
|
+
/** Runs a synchronous function and provides a Result catching
|
|
29
|
+
* any error */
|
|
30
|
+
export declare function attemptSync<T, A extends any[]>(fn: (...args: A) => T, ...args: A): Result<T, YError>;
|
|
31
|
+
/** Runs a synchronous function and provides a Result catching
|
|
32
|
+
* only known errors and letting unknown pass through */
|
|
33
|
+
export declare function attemptSyncFrom<C extends keyof YErrorRegistry, T, A extends any[]>(codes: C[], fn: (...args: A) => T, ...args: A): Result<T, YError<C>>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { looksLikeAYError, YError, hasYErrorCode, } from 'yerror';
|
|
2
|
+
/** Create a successful result */
|
|
3
|
+
export function ok(value) {
|
|
4
|
+
return {
|
|
5
|
+
ok: true,
|
|
6
|
+
value,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
/** Create a failure result using a YError code and debug values */
|
|
10
|
+
export function fail(code, debug, error) {
|
|
11
|
+
return {
|
|
12
|
+
ok: false,
|
|
13
|
+
error: new YError(code, debug, { cause: error }),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/** Wrap an existing error into a failure result */
|
|
17
|
+
export function failWith(error) {
|
|
18
|
+
return {
|
|
19
|
+
ok: false,
|
|
20
|
+
error: (looksLikeAYError(error)
|
|
21
|
+
? error
|
|
22
|
+
: new YError('E_UNEXPECTED', [], { cause: error })),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/** Transform a Promise into a Result catching any error */
|
|
26
|
+
export async function settle(promise) {
|
|
27
|
+
try {
|
|
28
|
+
const value = await promise;
|
|
29
|
+
return ok(value);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
return failWith(YError.cast(err));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Transform a Promise into a Result catching only known
|
|
36
|
+
* errors and letting unknown pass through */
|
|
37
|
+
export async function settleFrom(codes, promise) {
|
|
38
|
+
try {
|
|
39
|
+
const value = await promise;
|
|
40
|
+
return ok(value);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
for (const code of codes) {
|
|
44
|
+
if (hasYErrorCode(err, code)) {
|
|
45
|
+
return failWith(err);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Runs an asynchronous function and provides a Result catching
|
|
52
|
+
* any error */
|
|
53
|
+
export async function attempt(fn, ...args) {
|
|
54
|
+
try {
|
|
55
|
+
return ok(await fn(...args));
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
return failWith(YError.cast(err));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Runs an asynchronous function and provides a Result catching
|
|
62
|
+
* only known errors and letting unknown pass through */
|
|
63
|
+
export async function attemptFrom(codes, fn, ...args) {
|
|
64
|
+
try {
|
|
65
|
+
return ok(await fn(...args));
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
for (const code of codes) {
|
|
69
|
+
if (hasYErrorCode(err, code)) {
|
|
70
|
+
return failWith(err);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Runs a synchronous function and provides a Result catching
|
|
77
|
+
* any error */
|
|
78
|
+
export function attemptSync(fn, ...args) {
|
|
79
|
+
try {
|
|
80
|
+
return ok(fn(...args));
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
return failWith(YError.cast(err));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Runs a synchronous function and provides a Result catching
|
|
87
|
+
* only known errors and letting unknown pass through */
|
|
88
|
+
export function attemptSyncFrom(codes, fn, ...args) {
|
|
89
|
+
try {
|
|
90
|
+
return ok(fn(...args));
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
for (const code of codes) {
|
|
94
|
+
if (hasYErrorCode(err, code)) {
|
|
95
|
+
return failWith(err);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
throw err;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { describe, test, expect } from '@jest/globals';
|
|
2
|
+
import { ok, fail, failWith, settle, settleFrom, attempt, attemptFrom, attemptSync, attemptSyncFrom, } from './index.js';
|
|
3
|
+
import { YError } from 'yerror';
|
|
4
|
+
describe('zeerror', () => {
|
|
5
|
+
describe('ok()', () => {
|
|
6
|
+
test('should produce a result with a value', () => {
|
|
7
|
+
const result = ok({ my: 'result' });
|
|
8
|
+
if (result.ok) {
|
|
9
|
+
const value = result.value.my;
|
|
10
|
+
expect(value).toEqual('result');
|
|
11
|
+
// @ts-expect-error : expect error if type is casted
|
|
12
|
+
expect(result.value.not).toBeUndefined();
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
// @ts-expect-error : expect error since no value
|
|
16
|
+
expect(result.value).toBeUndefined();
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe('fail()', () => {
|
|
21
|
+
test('should produce a result with an error', () => {
|
|
22
|
+
const error = new Error('E_AOUCH');
|
|
23
|
+
const result = fail('E_ERROR_2', ['arg2.1', 'arg2.2'], error);
|
|
24
|
+
if (result.ok) {
|
|
25
|
+
// @ts-expect-error : expect error since no error
|
|
26
|
+
expect(result.error).toBeUndefined();
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// @ts-expect-error : expect error since nothing at this index
|
|
30
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
31
|
+
expect(result.error.debug).toEqual([`arg2.1`, `arg2.2`]);
|
|
32
|
+
expect(result.error.cause).toEqual(error);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe('failWith()', () => {
|
|
37
|
+
test('should produce a result with an error', () => {
|
|
38
|
+
const error = new Error('E_AOUCH');
|
|
39
|
+
const result = failWith(error);
|
|
40
|
+
if (result.ok) {
|
|
41
|
+
// @ts-expect-error : expect error since no error
|
|
42
|
+
expect(result.error).toBeUndefined();
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
expect(result.error.code).toEqual('E_UNEXPECTED');
|
|
46
|
+
expect(result.error.cause).toEqual(error);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
test('should produce a result with a yerror', () => {
|
|
50
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
51
|
+
const result = failWith(error);
|
|
52
|
+
if (result.ok) {
|
|
53
|
+
// @ts-expect-error : expect error since no error
|
|
54
|
+
expect(result.error).toBeUndefined();
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
58
|
+
// @ts-expect-error : expect error since nothing at this index
|
|
59
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
60
|
+
expect(result.error).toEqual(error);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
test('should handle non-error throws', () => {
|
|
64
|
+
const result = failWith('Something went wrong');
|
|
65
|
+
expect(result.ok).toBe(false);
|
|
66
|
+
if (!result.ok) {
|
|
67
|
+
expect(result.error.code).toEqual('E_UNEXPECTED');
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe('settle()', () => {
|
|
72
|
+
test('should produce a result with a promise of a value', async () => {
|
|
73
|
+
const resultPromise = settle(Promise.resolve({ my: 'result' }));
|
|
74
|
+
const result = await resultPromise;
|
|
75
|
+
if (result.ok) {
|
|
76
|
+
const value = result.value.my;
|
|
77
|
+
expect(value).toEqual('result');
|
|
78
|
+
// @ts-expect-error : expect error if type is casted
|
|
79
|
+
expect(result.value.not).toBeUndefined();
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// @ts-expect-error : expect error since no value
|
|
83
|
+
expect(result.value).toBeUndefined();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
test('should produce a result with a promise of an error', async () => {
|
|
87
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
88
|
+
const resultPromise = settle(Promise.reject(error));
|
|
89
|
+
const result = await resultPromise;
|
|
90
|
+
if (result.ok) {
|
|
91
|
+
// @ts-expect-error : expect error since no error
|
|
92
|
+
expect(result.error).toBeUndefined();
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
96
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
97
|
+
expect(result.error).toEqual(error);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe('settleFrom()', () => {
|
|
102
|
+
test('should produce a result with a promise of a value', async () => {
|
|
103
|
+
const resultPromise = settleFrom(['E_ERROR'], Promise.resolve({ my: 'result' }));
|
|
104
|
+
const result = await resultPromise;
|
|
105
|
+
if (result.ok) {
|
|
106
|
+
const value = result.value.my;
|
|
107
|
+
expect(value).toEqual('result');
|
|
108
|
+
// @ts-expect-error : expect error if type is casted
|
|
109
|
+
expect(result.value.not).toBeUndefined();
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// @ts-expect-error : expect error since no value
|
|
113
|
+
expect(result.value).toBeUndefined();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
test('should produce a result with a promise of an error', async () => {
|
|
117
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
118
|
+
const resultPromise = settleFrom(['E_ERROR_2'], Promise.reject(error));
|
|
119
|
+
const result = await resultPromise;
|
|
120
|
+
if (result.ok) {
|
|
121
|
+
// @ts-expect-error : expect error since no error
|
|
122
|
+
expect(result.error).toBeUndefined();
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
126
|
+
// @ts-expect-error : expect error since nothing at this index
|
|
127
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
128
|
+
expect(result.error).toEqual(error);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
test('should let unknown errors pass through', async () => {
|
|
132
|
+
const unknownError = new YError('E_ERROR_3', ['arg3.1', 'arg3.2']);
|
|
133
|
+
await expect(settleFrom(['E_ERROR_2'], Promise.reject(unknownError))).rejects.toThrow(unknownError);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe('attempt()', () => {
|
|
137
|
+
test('should produce a result with a promise of a value', async () => {
|
|
138
|
+
const resultPromise = attempt(async (test) => ({ my: test }), 'result');
|
|
139
|
+
const result = await resultPromise;
|
|
140
|
+
if (result.ok) {
|
|
141
|
+
const value = result.value.my;
|
|
142
|
+
expect(value).toEqual('result');
|
|
143
|
+
// @ts-expect-error : expect error if type is casted
|
|
144
|
+
expect(result.value.not).toBeUndefined();
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// @ts-expect-error : expect error since no value
|
|
148
|
+
expect(result.value).toBeUndefined();
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
test('should produce a result with a promise of an error', async () => {
|
|
152
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
153
|
+
const resultPromise = attempt(() => Promise.reject(error));
|
|
154
|
+
const result = await resultPromise;
|
|
155
|
+
if (result.ok) {
|
|
156
|
+
// @ts-expect-error : expect error since no error
|
|
157
|
+
expect(result.error).toBeUndefined();
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
161
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
162
|
+
expect(result.error).toEqual(error);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
test('should catch synchronous throws', async () => {
|
|
166
|
+
const error = new Error('Sync crash');
|
|
167
|
+
const result = await attempt(async () => {
|
|
168
|
+
throw error;
|
|
169
|
+
});
|
|
170
|
+
if (!result.ok) {
|
|
171
|
+
expect(result.error.cause).toEqual(error);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
throw new YError('E_UNEXPECTED_SUCCESS');
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
describe('attemptFrom()', () => {
|
|
179
|
+
test('should produce a result with a promise of a value', async () => {
|
|
180
|
+
const resultPromise = attemptFrom(['E_ERROR'], async (test) => ({ my: test }), 'result');
|
|
181
|
+
const result = await resultPromise;
|
|
182
|
+
if (result.ok) {
|
|
183
|
+
const value = result.value.my;
|
|
184
|
+
expect(value).toEqual('result');
|
|
185
|
+
// @ts-expect-error : expect error if type is casted
|
|
186
|
+
expect(result.value.not).toBeUndefined();
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
// @ts-expect-error : expect error since no value
|
|
190
|
+
expect(result.value).toBeUndefined();
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
test('should produce a result with a promise of an error', async () => {
|
|
194
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
195
|
+
const resultPromise = attemptFrom(['E_ERROR_2'], () => Promise.reject(error));
|
|
196
|
+
const result = await resultPromise;
|
|
197
|
+
if (result.ok) {
|
|
198
|
+
// @ts-expect-error : expect error since no error
|
|
199
|
+
expect(result.error).toBeUndefined();
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
203
|
+
// @ts-expect-error : expect error since nothing at this index
|
|
204
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
205
|
+
expect(result.error).toEqual(error);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
describe('attemptSync()', () => {
|
|
210
|
+
test('should produce a result with a value', () => {
|
|
211
|
+
const result = attemptSync((test) => ({ my: test }), 'result');
|
|
212
|
+
if (result.ok) {
|
|
213
|
+
const value = result.value.my;
|
|
214
|
+
expect(value).toEqual('result');
|
|
215
|
+
// @ts-expect-error : expect error if type is casted
|
|
216
|
+
expect(result.value.not).toBeUndefined();
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
// @ts-expect-error : expect error since no value
|
|
220
|
+
expect(result.value).toBeUndefined();
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
test('should produce a result with an error', async () => {
|
|
224
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
225
|
+
const result = attemptSync(() => {
|
|
226
|
+
throw error;
|
|
227
|
+
});
|
|
228
|
+
if (result.ok) {
|
|
229
|
+
// @ts-expect-error : expect error since no error
|
|
230
|
+
expect(result.error).toBeUndefined();
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
234
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
235
|
+
expect(result.error).toEqual(error);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
describe('attemptSyncFrom()', () => {
|
|
240
|
+
test('should produce a result with a value', () => {
|
|
241
|
+
const result = attemptSyncFrom(['E_ERROR'], (test) => ({ my: test }), 'result');
|
|
242
|
+
if (result.ok) {
|
|
243
|
+
const value = result.value.my;
|
|
244
|
+
expect(value).toEqual('result');
|
|
245
|
+
// @ts-expect-error : expect error if type is casted
|
|
246
|
+
expect(result.value.not).toBeUndefined();
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
// @ts-expect-error : expect error since no value
|
|
250
|
+
expect(result.value).toBeUndefined();
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
test('should produce a result with an error', () => {
|
|
254
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
255
|
+
const result = attemptSyncFrom(['E_ERROR_2'], () => {
|
|
256
|
+
throw error;
|
|
257
|
+
});
|
|
258
|
+
if (result.ok) {
|
|
259
|
+
// @ts-expect-error : expect error since no error
|
|
260
|
+
expect(result.error).toBeUndefined();
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
264
|
+
// @ts-expect-error : expect error since nothing at this index
|
|
265
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
266
|
+
expect(result.error).toEqual(error);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"metapak": {
|
|
3
|
+
"configs": [
|
|
4
|
+
"main",
|
|
5
|
+
"readme",
|
|
6
|
+
"tsesm",
|
|
7
|
+
"eslint",
|
|
8
|
+
"jest",
|
|
9
|
+
"codeclimate",
|
|
10
|
+
"ghactions",
|
|
11
|
+
"jsdocs"
|
|
12
|
+
],
|
|
13
|
+
"data": {
|
|
14
|
+
"files": "'src/**/*.ts'",
|
|
15
|
+
"testsFiles": "'src/**/*.test.ts'",
|
|
16
|
+
"distFiles": "'dist/**/*.js'",
|
|
17
|
+
"ignore": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"bundleFiles": [
|
|
21
|
+
"dist",
|
|
22
|
+
"src"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"name": "zresult",
|
|
27
|
+
"version": "1.0.0",
|
|
28
|
+
"description": "Wrap errors into results with that simple library.",
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "rimraf 'dist' && tsc --outDir dist",
|
|
31
|
+
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
|
|
32
|
+
"cli": "env NODE_ENV=${NODE_ENV:-cli}",
|
|
33
|
+
"commitlint": "commitlint",
|
|
34
|
+
"cover": "node --run jest -- --coverage",
|
|
35
|
+
"doc": "echo \"# API\" > API.md; jsdoc2md 'dist/**/*.js' >> API.md && git add API.md",
|
|
36
|
+
"format": "node --run prettier",
|
|
37
|
+
"jest": "NODE_OPTIONS=--experimental-vm-modules NODE_ENV=test jest",
|
|
38
|
+
"lint": "eslint 'src/**/*.ts'",
|
|
39
|
+
"metapak": "metapak",
|
|
40
|
+
"precommit": "node --run test && node --run lint && node --run build && node --run doc && node --run metapak -- -s",
|
|
41
|
+
"prettier": "prettier --write 'src/**/*.ts'",
|
|
42
|
+
"preversion": "node --run test && node --run lint && node --run build && node --run doc && node --run metapak -- -s",
|
|
43
|
+
"rebuild": "swc ./src -s -d dist -C jsc.target=es2022",
|
|
44
|
+
"test": "node --run jest",
|
|
45
|
+
"version": "node --run changelog"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=24.14.0"
|
|
49
|
+
},
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git://github.com/nfroidure/zresult.git"
|
|
53
|
+
},
|
|
54
|
+
"keywords": [
|
|
55
|
+
"error",
|
|
56
|
+
"why",
|
|
57
|
+
"better"
|
|
58
|
+
],
|
|
59
|
+
"author": {
|
|
60
|
+
"name": "Nicolas Froidure",
|
|
61
|
+
"email": "nicolas.froidure@insertafter.com",
|
|
62
|
+
"url": "http://insertafter.com/en/index.html"
|
|
63
|
+
},
|
|
64
|
+
"license": "MIT",
|
|
65
|
+
"bugs": {
|
|
66
|
+
"url": "https://github.com/nfroidure/zresult/issues"
|
|
67
|
+
},
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"yerror": "^11.0.0"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@commitlint/cli": "^20.5.0",
|
|
73
|
+
"@commitlint/config-conventional": "^20.5.0",
|
|
74
|
+
"@eslint/js": "^10.0.1",
|
|
75
|
+
"@swc/cli": "^0.8.1",
|
|
76
|
+
"@swc/core": "^1.15.24",
|
|
77
|
+
"@swc/jest": "^0.2.39",
|
|
78
|
+
"conventional-changelog": "^7.2.0",
|
|
79
|
+
"eslint": "^10.2.0",
|
|
80
|
+
"eslint-config-prettier": "^10.1.8",
|
|
81
|
+
"eslint-plugin-jest": "^29.15.1",
|
|
82
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
83
|
+
"jest": "^30.3.0",
|
|
84
|
+
"jsdoc-to-markdown": "^9.1.3",
|
|
85
|
+
"metapak": "^7.1.0",
|
|
86
|
+
"metapak-nfroidure": "22.1.1",
|
|
87
|
+
"prettier": "^3.8.1",
|
|
88
|
+
"rimraf": "^6.1.3",
|
|
89
|
+
"typescript": "^6.0.2",
|
|
90
|
+
"typescript-eslint": "^8.58.0"
|
|
91
|
+
},
|
|
92
|
+
"contributors": [],
|
|
93
|
+
"files": [
|
|
94
|
+
"dist",
|
|
95
|
+
"src",
|
|
96
|
+
"LICENSE",
|
|
97
|
+
"README.md",
|
|
98
|
+
"CHANGELOG.md"
|
|
99
|
+
],
|
|
100
|
+
"prettier": {
|
|
101
|
+
"semi": true,
|
|
102
|
+
"printWidth": 80,
|
|
103
|
+
"singleQuote": true,
|
|
104
|
+
"trailingComma": "all",
|
|
105
|
+
"proseWrap": "always"
|
|
106
|
+
},
|
|
107
|
+
"funding": {
|
|
108
|
+
"type": "individual",
|
|
109
|
+
"url": "https://github.com/sponsors/nfroidure"
|
|
110
|
+
},
|
|
111
|
+
"overrides": {
|
|
112
|
+
"typescript-eslint": {
|
|
113
|
+
"typescript": "^6"
|
|
114
|
+
},
|
|
115
|
+
"@typescript-eslint/eslint-plugin": {
|
|
116
|
+
"typescript": "^6"
|
|
117
|
+
},
|
|
118
|
+
"@typescript-eslint/parser": {
|
|
119
|
+
"typescript": "^6"
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"type": "module",
|
|
123
|
+
"main": "dist/index.js",
|
|
124
|
+
"types": "dist/index.d.ts",
|
|
125
|
+
"jest": {
|
|
126
|
+
"coverageReporters": [
|
|
127
|
+
"lcov"
|
|
128
|
+
],
|
|
129
|
+
"testPathIgnorePatterns": [
|
|
130
|
+
"/node_modules/"
|
|
131
|
+
],
|
|
132
|
+
"roots": [
|
|
133
|
+
"<rootDir>/src"
|
|
134
|
+
],
|
|
135
|
+
"transform": {
|
|
136
|
+
"^.+\\.tsx?$": [
|
|
137
|
+
"@swc/jest",
|
|
138
|
+
{}
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
"testEnvironment": "node",
|
|
142
|
+
"moduleNameMapper": {
|
|
143
|
+
"(.+)\\.js": "$1"
|
|
144
|
+
},
|
|
145
|
+
"extensionsToTreatAsEsm": [
|
|
146
|
+
".ts"
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { describe, test, expect } from '@jest/globals';
|
|
2
|
+
import {
|
|
3
|
+
ok,
|
|
4
|
+
fail,
|
|
5
|
+
failWith,
|
|
6
|
+
settle,
|
|
7
|
+
settleFrom,
|
|
8
|
+
attempt,
|
|
9
|
+
attemptFrom,
|
|
10
|
+
attemptSync,
|
|
11
|
+
attemptSyncFrom,
|
|
12
|
+
} from './index.js';
|
|
13
|
+
import { YError } from 'yerror';
|
|
14
|
+
|
|
15
|
+
declare module 'yerror' {
|
|
16
|
+
interface YErrorRegistry {
|
|
17
|
+
E_ERROR: `arg${number}`[];
|
|
18
|
+
E_ERROR_1: [string, string];
|
|
19
|
+
E_ERROR_2: [`arg2.1`, `arg2.2`];
|
|
20
|
+
E_ERROR_3: [`arg3.1`, `arg3.2`];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('zresult', () => {
|
|
25
|
+
describe('ok()', () => {
|
|
26
|
+
test('should produce a result with a value', () => {
|
|
27
|
+
const result = ok({ my: 'result' } as const);
|
|
28
|
+
|
|
29
|
+
if (result.ok) {
|
|
30
|
+
const value: string = result.value.my;
|
|
31
|
+
|
|
32
|
+
expect(value).toEqual('result');
|
|
33
|
+
// @ts-expect-error : expect error if type is casted
|
|
34
|
+
expect(result.value.not).toBeUndefined();
|
|
35
|
+
} else {
|
|
36
|
+
// @ts-expect-error : expect error since no value
|
|
37
|
+
expect(result.value).toBeUndefined();
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe('fail()', () => {
|
|
43
|
+
test('should produce a result with an error', () => {
|
|
44
|
+
const error = new Error('E_AOUCH');
|
|
45
|
+
const result = fail('E_ERROR_2', ['arg2.1', 'arg2.2'], error);
|
|
46
|
+
|
|
47
|
+
if (result.ok) {
|
|
48
|
+
// @ts-expect-error : expect error since no error
|
|
49
|
+
expect(result.error).toBeUndefined();
|
|
50
|
+
} else {
|
|
51
|
+
// @ts-expect-error : expect error since nothing at this index
|
|
52
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
53
|
+
expect(result.error.debug).toEqual([`arg2.1`, `arg2.2`]);
|
|
54
|
+
expect(result.error.cause).toEqual(error);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('failWith()', () => {
|
|
60
|
+
test('should produce a result with an error', () => {
|
|
61
|
+
const error = new Error('E_AOUCH');
|
|
62
|
+
const result = failWith(error);
|
|
63
|
+
|
|
64
|
+
if (result.ok) {
|
|
65
|
+
// @ts-expect-error : expect error since no error
|
|
66
|
+
expect(result.error).toBeUndefined();
|
|
67
|
+
} else {
|
|
68
|
+
expect(result.error.code).toEqual('E_UNEXPECTED');
|
|
69
|
+
expect(result.error.cause).toEqual(error);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('should produce a result with a yerror', () => {
|
|
74
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
75
|
+
const result = failWith(error);
|
|
76
|
+
|
|
77
|
+
if (result.ok) {
|
|
78
|
+
// @ts-expect-error : expect error since no error
|
|
79
|
+
expect(result.error).toBeUndefined();
|
|
80
|
+
} else {
|
|
81
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
82
|
+
// @ts-expect-error : expect error since nothing at this index
|
|
83
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
84
|
+
expect(result.error).toEqual(error);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('should handle non-error throws', () => {
|
|
89
|
+
const result = failWith('Something went wrong' as unknown as Error);
|
|
90
|
+
|
|
91
|
+
expect(result.ok).toBe(false);
|
|
92
|
+
if (!result.ok) {
|
|
93
|
+
expect(result.error.code).toEqual('E_UNEXPECTED');
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
describe('settle()', () => {
|
|
99
|
+
test('should produce a result with a promise of a value', async () => {
|
|
100
|
+
const resultPromise = settle(Promise.resolve({ my: 'result' } as const));
|
|
101
|
+
const result = await resultPromise;
|
|
102
|
+
|
|
103
|
+
if (result.ok) {
|
|
104
|
+
const value: string = result.value.my;
|
|
105
|
+
|
|
106
|
+
expect(value).toEqual('result');
|
|
107
|
+
// @ts-expect-error : expect error if type is casted
|
|
108
|
+
expect(result.value.not).toBeUndefined();
|
|
109
|
+
} else {
|
|
110
|
+
// @ts-expect-error : expect error since no value
|
|
111
|
+
expect(result.value).toBeUndefined();
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test('should produce a result with a promise of an error', async () => {
|
|
116
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
117
|
+
const resultPromise = settle(Promise.reject(error));
|
|
118
|
+
const result = await resultPromise;
|
|
119
|
+
|
|
120
|
+
if (result.ok) {
|
|
121
|
+
// @ts-expect-error : expect error since no error
|
|
122
|
+
expect(result.error).toBeUndefined();
|
|
123
|
+
} else {
|
|
124
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
125
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
126
|
+
expect(result.error).toEqual(error);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe('settleFrom()', () => {
|
|
132
|
+
test('should produce a result with a promise of a value', async () => {
|
|
133
|
+
const resultPromise = settleFrom(
|
|
134
|
+
['E_ERROR'],
|
|
135
|
+
Promise.resolve({ my: 'result' } as const),
|
|
136
|
+
);
|
|
137
|
+
const result = await resultPromise;
|
|
138
|
+
|
|
139
|
+
if (result.ok) {
|
|
140
|
+
const value: string = result.value.my;
|
|
141
|
+
|
|
142
|
+
expect(value).toEqual('result');
|
|
143
|
+
// @ts-expect-error : expect error if type is casted
|
|
144
|
+
expect(result.value.not).toBeUndefined();
|
|
145
|
+
} else {
|
|
146
|
+
// @ts-expect-error : expect error since no value
|
|
147
|
+
expect(result.value).toBeUndefined();
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('should produce a result with a promise of an error', async () => {
|
|
152
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
153
|
+
const resultPromise = settleFrom(['E_ERROR_2'], Promise.reject(error));
|
|
154
|
+
const result = await resultPromise;
|
|
155
|
+
|
|
156
|
+
if (result.ok) {
|
|
157
|
+
// @ts-expect-error : expect error since no error
|
|
158
|
+
expect(result.error).toBeUndefined();
|
|
159
|
+
} else {
|
|
160
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
161
|
+
// @ts-expect-error : expect error since nothing at this index
|
|
162
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
163
|
+
expect(result.error).toEqual(error);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('should let unknown errors pass through', async () => {
|
|
168
|
+
const unknownError = new YError('E_ERROR_3', ['arg3.1', 'arg3.2']);
|
|
169
|
+
|
|
170
|
+
await expect(
|
|
171
|
+
settleFrom(['E_ERROR_2'], Promise.reject(unknownError)),
|
|
172
|
+
).rejects.toThrow(unknownError);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
describe('attempt()', () => {
|
|
177
|
+
test('should produce a result with a promise of a value', async () => {
|
|
178
|
+
const resultPromise = attempt(
|
|
179
|
+
async (test: string) => ({ my: test }),
|
|
180
|
+
'result',
|
|
181
|
+
);
|
|
182
|
+
const result = await resultPromise;
|
|
183
|
+
|
|
184
|
+
if (result.ok) {
|
|
185
|
+
const value: string = result.value.my;
|
|
186
|
+
|
|
187
|
+
expect(value).toEqual('result');
|
|
188
|
+
// @ts-expect-error : expect error if type is casted
|
|
189
|
+
expect(result.value.not).toBeUndefined();
|
|
190
|
+
} else {
|
|
191
|
+
// @ts-expect-error : expect error since no value
|
|
192
|
+
expect(result.value).toBeUndefined();
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test('should produce a result with a promise of an error', async () => {
|
|
197
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
198
|
+
const resultPromise = attempt(() => Promise.reject(error));
|
|
199
|
+
const result = await resultPromise;
|
|
200
|
+
|
|
201
|
+
if (result.ok) {
|
|
202
|
+
// @ts-expect-error : expect error since no error
|
|
203
|
+
expect(result.error).toBeUndefined();
|
|
204
|
+
} else {
|
|
205
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
206
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
207
|
+
expect(result.error).toEqual(error);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test('should catch synchronous throws', async () => {
|
|
212
|
+
const error = new Error('Sync crash');
|
|
213
|
+
const result = await attempt(async (): Promise<undefined> => {
|
|
214
|
+
throw error;
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
if (!result.ok) {
|
|
218
|
+
expect(result.error.cause).toEqual(error);
|
|
219
|
+
} else {
|
|
220
|
+
throw new YError('E_UNEXPECTED_SUCCESS');
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
describe('attemptFrom()', () => {
|
|
226
|
+
test('should produce a result with a promise of a value', async () => {
|
|
227
|
+
const resultPromise = attemptFrom(
|
|
228
|
+
['E_ERROR'],
|
|
229
|
+
async (test: string) => ({ my: test }),
|
|
230
|
+
'result',
|
|
231
|
+
);
|
|
232
|
+
const result = await resultPromise;
|
|
233
|
+
|
|
234
|
+
if (result.ok) {
|
|
235
|
+
const value: string = result.value.my;
|
|
236
|
+
|
|
237
|
+
expect(value).toEqual('result');
|
|
238
|
+
// @ts-expect-error : expect error if type is casted
|
|
239
|
+
expect(result.value.not).toBeUndefined();
|
|
240
|
+
} else {
|
|
241
|
+
// @ts-expect-error : expect error since no value
|
|
242
|
+
expect(result.value).toBeUndefined();
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
test('should produce a result with a promise of an error', async () => {
|
|
247
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
248
|
+
const resultPromise = attemptFrom(
|
|
249
|
+
['E_ERROR_2'],
|
|
250
|
+
(): Promise<undefined> => Promise.reject(error),
|
|
251
|
+
);
|
|
252
|
+
const result = await resultPromise;
|
|
253
|
+
|
|
254
|
+
if (result.ok) {
|
|
255
|
+
// @ts-expect-error : expect error since no error
|
|
256
|
+
expect(result.error).toBeUndefined();
|
|
257
|
+
} else {
|
|
258
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
259
|
+
// @ts-expect-error : expect error since nothing at this index
|
|
260
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
261
|
+
expect(result.error).toEqual(error);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
describe('attemptSync()', () => {
|
|
267
|
+
test('should produce a result with a value', () => {
|
|
268
|
+
const result = attemptSync((test: string) => ({ my: test }), 'result');
|
|
269
|
+
|
|
270
|
+
if (result.ok) {
|
|
271
|
+
const value: string = result.value.my;
|
|
272
|
+
|
|
273
|
+
expect(value).toEqual('result');
|
|
274
|
+
// @ts-expect-error : expect error if type is casted
|
|
275
|
+
expect(result.value.not).toBeUndefined();
|
|
276
|
+
} else {
|
|
277
|
+
// @ts-expect-error : expect error since no value
|
|
278
|
+
expect(result.value).toBeUndefined();
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
test('should produce a result with an error', async () => {
|
|
283
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
284
|
+
const result = attemptSync(() => {
|
|
285
|
+
throw error;
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
if (result.ok) {
|
|
289
|
+
// @ts-expect-error : expect error since no error
|
|
290
|
+
expect(result.error).toBeUndefined();
|
|
291
|
+
} else {
|
|
292
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
293
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
294
|
+
expect(result.error).toEqual(error);
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe('attemptSyncFrom()', () => {
|
|
300
|
+
test('should produce a result with a value', () => {
|
|
301
|
+
const result = attemptSyncFrom(
|
|
302
|
+
['E_ERROR'],
|
|
303
|
+
(test: string) => ({ my: test }),
|
|
304
|
+
'result',
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
if (result.ok) {
|
|
308
|
+
const value: string = result.value.my;
|
|
309
|
+
|
|
310
|
+
expect(value).toEqual('result');
|
|
311
|
+
// @ts-expect-error : expect error if type is casted
|
|
312
|
+
expect(result.value.not).toBeUndefined();
|
|
313
|
+
} else {
|
|
314
|
+
// @ts-expect-error : expect error since no value
|
|
315
|
+
expect(result.value).toBeUndefined();
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test('should produce a result with an error', () => {
|
|
320
|
+
const error = new YError('E_ERROR_2', ['arg2.1', 'arg2.2']);
|
|
321
|
+
const result = attemptSyncFrom(['E_ERROR_2'], (): undefined => {
|
|
322
|
+
throw error;
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
if (result.ok) {
|
|
326
|
+
// @ts-expect-error : expect error since no error
|
|
327
|
+
expect(result.error).toBeUndefined();
|
|
328
|
+
} else {
|
|
329
|
+
expect(result.error.debug[1]).toEqual('arg2.2');
|
|
330
|
+
// @ts-expect-error : expect error since nothing at this index
|
|
331
|
+
expect(result.error.debug[2]).toBeUndefined();
|
|
332
|
+
expect(result.error).toEqual(error);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type YErrorDebug,
|
|
3
|
+
type YErrorRegistry,
|
|
4
|
+
looksLikeAYError,
|
|
5
|
+
YError,
|
|
6
|
+
hasYErrorCode,
|
|
7
|
+
} from 'yerror';
|
|
8
|
+
|
|
9
|
+
/** A type to encapsulate a result that can either be
|
|
10
|
+
* failure or a success */
|
|
11
|
+
export type Result<T, E extends Error | YError> =
|
|
12
|
+
| { readonly ok: true; readonly value: T }
|
|
13
|
+
| { readonly ok: false; readonly error: E };
|
|
14
|
+
|
|
15
|
+
/** Create a successful result */
|
|
16
|
+
export function ok<T>(value: T): Result<T, never> {
|
|
17
|
+
return {
|
|
18
|
+
ok: true,
|
|
19
|
+
value,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Create a failure result using a YError code and debug values */
|
|
24
|
+
export function fail<C extends keyof YErrorRegistry>(
|
|
25
|
+
code: C,
|
|
26
|
+
debug: YErrorDebug<C>,
|
|
27
|
+
error?: Error,
|
|
28
|
+
): Result<never, YError<C>> {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
error: new YError(code, debug, { cause: error }),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Wrap an existing error into a failure result */
|
|
36
|
+
export function failWith<E extends Error | YError>(
|
|
37
|
+
error: E,
|
|
38
|
+
): Result<
|
|
39
|
+
never,
|
|
40
|
+
E extends YError<infer C> ? YError<C> : YError<'E_UNEXPECTED'>
|
|
41
|
+
> {
|
|
42
|
+
return {
|
|
43
|
+
ok: false,
|
|
44
|
+
error: (looksLikeAYError(error)
|
|
45
|
+
? error
|
|
46
|
+
: new YError('E_UNEXPECTED', [], { cause: error })) as E extends YError<
|
|
47
|
+
infer C
|
|
48
|
+
>
|
|
49
|
+
? YError<C>
|
|
50
|
+
: YError<'E_UNEXPECTED'>,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Transform a Promise into a Result catching any error */
|
|
55
|
+
export async function settle<T>(
|
|
56
|
+
promise: Promise<T>,
|
|
57
|
+
): Promise<Result<T, YError>> {
|
|
58
|
+
try {
|
|
59
|
+
const value = await promise;
|
|
60
|
+
|
|
61
|
+
return ok(value);
|
|
62
|
+
} catch (err) {
|
|
63
|
+
return failWith(YError.cast(err as Error));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Transform a Promise into a Result catching only known
|
|
68
|
+
* errors and letting unknown pass through */
|
|
69
|
+
export async function settleFrom<C extends keyof YErrorRegistry, T>(
|
|
70
|
+
codes: C[],
|
|
71
|
+
promise: Promise<T>,
|
|
72
|
+
): Promise<Result<T, YError<C>>> {
|
|
73
|
+
try {
|
|
74
|
+
const value = await promise;
|
|
75
|
+
|
|
76
|
+
return ok(value);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
for (const code of codes) {
|
|
79
|
+
if (hasYErrorCode(err, code)) {
|
|
80
|
+
return failWith(err);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Runs an asynchronous function and provides a Result catching
|
|
88
|
+
* any error */
|
|
89
|
+
export async function attempt<
|
|
90
|
+
T,
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
92
|
+
A extends any[],
|
|
93
|
+
>(fn: (...args: A) => Promise<T>, ...args: A): Promise<Result<T, YError>> {
|
|
94
|
+
try {
|
|
95
|
+
return ok(await fn(...args));
|
|
96
|
+
} catch (err) {
|
|
97
|
+
return failWith(YError.cast(err as Error));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Runs an asynchronous function and provides a Result catching
|
|
102
|
+
* only known errors and letting unknown pass through */
|
|
103
|
+
export async function attemptFrom<
|
|
104
|
+
C extends keyof YErrorRegistry,
|
|
105
|
+
T,
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
107
|
+
A extends any[],
|
|
108
|
+
>(
|
|
109
|
+
codes: C[],
|
|
110
|
+
fn: (...args: A) => Promise<T>,
|
|
111
|
+
...args: A
|
|
112
|
+
): Promise<Result<T, YError<C>>> {
|
|
113
|
+
try {
|
|
114
|
+
return ok(await fn(...args));
|
|
115
|
+
} catch (err) {
|
|
116
|
+
for (const code of codes) {
|
|
117
|
+
if (hasYErrorCode(err, code)) {
|
|
118
|
+
return failWith(err);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Runs a synchronous function and provides a Result catching
|
|
126
|
+
* any error */
|
|
127
|
+
export function attemptSync<
|
|
128
|
+
T,
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
130
|
+
A extends any[],
|
|
131
|
+
>(fn: (...args: A) => T, ...args: A): Result<T, YError> {
|
|
132
|
+
try {
|
|
133
|
+
return ok(fn(...args));
|
|
134
|
+
} catch (err) {
|
|
135
|
+
return failWith(YError.cast(err as Error));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Runs a synchronous function and provides a Result catching
|
|
140
|
+
* only known errors and letting unknown pass through */
|
|
141
|
+
export function attemptSyncFrom<
|
|
142
|
+
C extends keyof YErrorRegistry,
|
|
143
|
+
T,
|
|
144
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
145
|
+
A extends any[],
|
|
146
|
+
>(codes: C[], fn: (...args: A) => T, ...args: A): Result<T, YError<C>> {
|
|
147
|
+
try {
|
|
148
|
+
return ok(fn(...args));
|
|
149
|
+
} catch (err) {
|
|
150
|
+
for (const code of codes) {
|
|
151
|
+
if (hasYErrorCode(err, code)) {
|
|
152
|
+
return failWith(err);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
throw err;
|
|
156
|
+
}
|
|
157
|
+
}
|