catch-match 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -39,6 +39,10 @@ try {
39
39
  //> final
40
40
  ```
41
41
 
42
+ ## Features
43
+
44
+ Supporting sync/async functions
45
+
42
46
  ## Getting started
43
47
 
44
48
  ```shell
@@ -100,3 +104,46 @@ const result = $try(() => {
100
104
 
101
105
  console.log(result); // { error: SyntaxError, result: undefined }
102
106
  ```
107
+
108
+ ## Promises example
109
+
110
+ ```typescript
111
+ class AuthError extends Error {}
112
+
113
+ function proc(event: string) {
114
+ return $try(() => new Promise((resolve, reject) => {
115
+ switch (event) {
116
+ case 'resolve':
117
+ resolve('resolved')
118
+ break;
119
+ case 'reject':
120
+ reject('rejected')
121
+ break;
122
+ case 'syntax':
123
+ throw SyntaxError
124
+ case 'auth':
125
+ throw AuthError
126
+ case 'error':
127
+ throw 'error'
128
+ default:
129
+ throw 'other errors'
130
+ }
131
+ }).catch('error', () => {
132
+ // console.log('error')
133
+ }).catch([SyntaxError, AuthError], (error) => {
134
+ // console.log(error)
135
+ }).other((error) => {
136
+ // console.log(error)
137
+ }).finally(({ value, error }) => {
138
+ // console.log({ value, error })
139
+ })
140
+ }
141
+
142
+ await proc('resolve') // { value: 'resolved' }}
143
+ await proc('reject') // { error: 'rejected' }
144
+
145
+ await proc('syntax') // { error: SyntaxError }
146
+ await proc('auth') // { error: AuthError }
147
+ await proc('error') // { error: 'error' }
148
+ await proc('other') // { error: 'other errors' }
149
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catch-match",
3
- "version": "2.0.1",
3
+ "version": "3.0.0",
4
4
  "repository": {
5
5
  "url": "https://github.com/kobzarvs/catch-match"
6
6
  },
@@ -12,7 +12,13 @@
12
12
  "errors",
13
13
  "exceptions",
14
14
  "throw",
15
- "finally"
15
+ "finally",
16
+ "promises",
17
+ "resolve",
18
+ "reject",
19
+ "flow",
20
+ "control",
21
+ "process"
16
22
  ],
17
23
  "main": "dist/main.js",
18
24
  "scripts": {
@@ -1,223 +1,502 @@
1
- import $try from '../main';
2
-
3
- test('should be return result from `finally` branch', () => {
4
- let matchReferenceError = jest.fn();
5
- let matchArrayOfErrors = jest.fn();
6
- let matchOther = jest.fn();
7
- let matchFinally = jest.fn();
8
-
9
- const result = $try(() => {
10
- return [1, 2, 3];
11
- }).catch(ReferenceError, () => {
12
- matchReferenceError();
13
- }).catch([TypeError, SyntaxError], () => {
14
- matchArrayOfErrors();
15
- }).other((error) => {
16
- matchOther(error);
17
- }).finally(({ result, error }) => {
18
- matchFinally({ result, error });
19
- return result;
20
- });
21
-
22
- expect(matchReferenceError).not.toBeCalled();
23
- expect(matchArrayOfErrors).not.toBeCalled();
24
- expect(matchOther).not.toBeCalled();
25
- expect(matchFinally).toBeCalled();
26
- expect(result).toEqual({ error: undefined, result: [1, 2, 3] });
27
- });
28
-
29
- test('should be match single exception', () => {
30
- let matchReferenceError = jest.fn();
31
- let matchArrayOfErrors = jest.fn();
32
- let matchOther = jest.fn();
33
- let matchFinally = jest.fn();
34
-
35
- const result = $try(() => {
36
- throw ReferenceError;
37
- }).catch(ReferenceError, () => {
38
- matchReferenceError();
39
- }).catch([TypeError, SyntaxError], () => {
40
- matchArrayOfErrors();
41
- }).other((error) => {
42
- matchOther(error);
43
- }).finally(({ result, error }) => {
44
- matchFinally({ result, error });
45
- return result;
46
- });
47
-
48
- expect(matchReferenceError).toBeCalled();
49
- expect(matchArrayOfErrors).not.toBeCalled();
50
- expect(matchOther).not.toBeCalled();
51
- expect(matchFinally).toBeCalled();
52
- expect(result).toEqual({ error: ReferenceError, result: undefined });
53
- });
54
-
55
- test('should be match array of exceptions', () => {
56
- let matchReferenceError = jest.fn();
57
- let matchArrayOfErrors = jest.fn();
58
- let matchOther = jest.fn();
59
- let matchFinally = jest.fn();
60
-
61
- const result = $try(() => {
62
- throw SyntaxError;
63
- }).catch(ReferenceError, () => {
64
- matchReferenceError();
65
- }).catch([TypeError, SyntaxError], () => {
66
- matchArrayOfErrors();
67
- }).other((error) => {
68
- matchOther(error);
69
- }).finally(({ result, error }) => {
70
- matchFinally({ result, error });
71
- return result;
72
- });
73
-
74
- expect(matchReferenceError).not.toBeCalled();
75
- expect(matchArrayOfErrors).toBeCalled();
76
- expect(matchOther).not.toBeCalled();
77
- expect(matchFinally).toBeCalled();
78
- expect(result).toEqual({ error: SyntaxError, result: undefined });
79
- });
80
-
81
- test('should be match any type of exception', () => {
82
- let matchReferenceError = jest.fn();
83
- let matchArrayOfErrors = jest.fn();
84
- let matchOther = jest.fn();
85
- let matchFinally = jest.fn();
86
-
87
- const result = $try(() => {
88
- throw 'error';
89
- }).catch(ReferenceError, () => {
90
- matchReferenceError();
91
- }).catch([TypeError, SyntaxError], () => {
92
- matchArrayOfErrors();
93
- }).other((error) => {
94
- matchOther(error);
95
- }).finally(({ result, error }) => {
96
- matchFinally({ result, error });
97
- return result;
98
- });
99
-
100
- expect(matchReferenceError).not.toBeCalled();
101
- expect(matchArrayOfErrors).not.toBeCalled();
102
- expect(matchOther).toBeCalled();
103
- expect(matchFinally).toBeCalled();
104
- expect(result).toEqual({ error: 'error', result: undefined });
105
- });
106
-
107
- test('should be match custom exceptions', () => {
108
- let matchCustomError = jest.fn();
109
- let matchArrayOfErrors = jest.fn();
110
- let matchOther = jest.fn();
111
- let matchFinally = jest.fn();
112
-
113
- class CustomError extends Error {
114
- }
115
-
116
- const result = $try(() => {
117
- throw CustomError;
118
- }).catch(CustomError, () => {
119
- matchCustomError();
120
- }).catch([TypeError, SyntaxError], () => {
121
- matchArrayOfErrors();
122
- }).other((error) => {
123
- matchOther(error);
124
- }).finally(({ result, error }) => {
125
- matchFinally({ result, error });
126
- return result;
127
- });
128
-
129
- expect(matchCustomError).toBeCalled();
130
- expect(matchArrayOfErrors).not.toBeCalled();
131
- expect(matchOther).not.toBeCalled();
132
- expect(matchFinally).toBeCalled();
133
- expect(result).toEqual({ error: CustomError, result: undefined });
134
- });
135
-
136
- test('should be return result from `finally` branch without `other`', () => {
137
- let matchCustomError = jest.fn();
138
- let matchArrayOfErrors = jest.fn();
139
- let matchOther = jest.fn();
140
- let matchFinally = jest.fn();
141
-
142
- class CustomError extends Error {
143
- }
144
-
145
- const result = $try(() => {
146
- throw CustomError;
147
- }).catch([TypeError, SyntaxError], () => {
148
- matchArrayOfErrors();
149
- }).finally(({ result, error }) => {
150
- matchFinally({ result, error });
151
- return result;
152
- });
153
-
154
- expect(matchCustomError).not.toBeCalled();
155
- expect(matchArrayOfErrors).not.toBeCalled();
156
- expect(matchOther).not.toBeCalled();
157
- expect(matchFinally).toBeCalled();
158
- expect(result).toEqual({ error: CustomError, result: undefined });
159
- });
160
-
161
-
162
- test('should be return result from `catch` branch', () => {
163
- let matchCustomError = jest.fn();
164
- let matchArrayOfErrors = jest.fn();
165
- let matchOther = jest.fn();
166
- let matchFinally = jest.fn();
1
+ import $try, { PromisedTryReturn } from '../main';
2
+
3
+ describe('sync version', () => {
4
+ test('should be return result from `finally` branch', () => {
5
+ let matchReferenceError = jest.fn();
6
+ let matchArrayOfErrors = jest.fn();
7
+ let matchOther = jest.fn();
8
+ let matchFinally = jest.fn();
9
+
10
+ const result = $try(() => {
11
+ return [1, 2, 3];
12
+ }).catch(ReferenceError, () => {
13
+ matchReferenceError();
14
+ }).catch([TypeError, SyntaxError], (error) => {
15
+ matchArrayOfErrors(error);
16
+ }).other((error) => {
17
+ matchOther(error);
18
+ }).finally(({ value, error }) => { //?
19
+ matchFinally({ value, error });
20
+ });
21
+
22
+ expect(matchReferenceError).not.toBeCalled();
23
+ expect(matchArrayOfErrors).not.toBeCalled();
24
+ expect(matchOther).not.toBeCalled();
25
+ expect(matchFinally).toBeCalled();
26
+ expect(result).toMatchObject({ error: undefined, value: [1, 2, 3] });
27
+ });
167
28
 
168
- class CustomError extends Error {
169
- }
29
+ test('should be match single exception', () => {
30
+ let matchReferenceError = jest.fn();
31
+ let matchArrayOfErrors = jest.fn();
32
+ let matchOther = jest.fn();
33
+ let matchFinally = jest.fn();
34
+
35
+ const result = $try(() => {
36
+ throw ReferenceError;
37
+ }).catch(ReferenceError, () => {
38
+ matchReferenceError();
39
+ }).catch([TypeError, SyntaxError], (error) => {
40
+ matchArrayOfErrors(error);
41
+ }).other((error) => {
42
+ matchOther(error);
43
+ }).finally(({ value, error }) => {
44
+ matchFinally({ value, error });
45
+ return value; // ?
46
+ });
47
+
48
+ expect(matchReferenceError).toBeCalled();
49
+ expect(matchArrayOfErrors).not.toBeCalled();
50
+ expect(matchOther).not.toBeCalled();
51
+ expect(matchFinally).toBeCalled();
52
+ expect(result).toMatchObject({ error: ReferenceError, value: undefined });
53
+ });
170
54
 
171
- const result = $try(() => {
172
- throw CustomError;
173
- }).catch([TypeError, SyntaxError], () => {
174
- matchArrayOfErrors();
55
+ test('should be match array of exceptions', () => {
56
+ let matchReferenceError = jest.fn();
57
+ let matchArrayOfErrors = jest.fn();
58
+ let matchOther = jest.fn();
59
+ let matchFinally = jest.fn();
60
+
61
+ const result = $try(() => {
62
+ throw SyntaxError;
63
+ }).catch(ReferenceError, () => {
64
+ matchReferenceError();
65
+ }).catch([TypeError, SyntaxError], (error) => {
66
+ matchArrayOfErrors(error);
67
+ }).other((error) => {
68
+ matchOther(error);
69
+ }).finally(({ value, error }) => {
70
+ matchFinally({ value, error });
71
+ return value; // ?
72
+ });
73
+
74
+ expect(matchReferenceError).not.toBeCalled();
75
+ expect(matchArrayOfErrors).toBeCalledWith(SyntaxError);
76
+ expect(matchOther).not.toBeCalled();
77
+ expect(matchFinally).toBeCalled();
78
+ expect(result).toMatchObject({ error: SyntaxError, value: undefined });
175
79
  });
176
80
 
177
- expect(matchCustomError).not.toBeCalled();
178
- expect(matchArrayOfErrors).not.toBeCalled();
179
- expect(matchOther).not.toBeCalled();
180
- expect(matchFinally).not.toBeCalled();
181
- expect(result).toMatchObject({ error: CustomError, result: undefined });
182
- });
81
+ test('should be match any type of exception', () => {
82
+ let matchReferenceError = jest.fn();
83
+ let matchArrayOfErrors = jest.fn();
84
+ let matchOther = jest.fn();
85
+ let matchFinally = jest.fn();
86
+
87
+ const result = $try(() => {
88
+ throw 'error';
89
+ }).catch(ReferenceError, () => {
90
+ matchReferenceError();
91
+ }).catch([TypeError, SyntaxError], (error) => {
92
+ matchArrayOfErrors(error);
93
+ }).other((error) => {
94
+ matchOther(error);
95
+ }).finally(({ value, error }) => {
96
+ matchFinally({ value, error });
97
+ return value; // ?
98
+ });
99
+
100
+ expect(matchReferenceError).not.toBeCalled();
101
+ expect(matchArrayOfErrors).not.toBeCalled();
102
+ expect(matchOther).toBeCalled();
103
+ expect(matchFinally).toBeCalled();
104
+ expect(result).toMatchObject({ error: 'error', value: undefined });
105
+ });
183
106
 
107
+ test('should be match custom exceptions', () => {
108
+ let matchCustomError = jest.fn();
109
+ let matchArrayOfErrors = jest.fn();
110
+ let matchOther = jest.fn();
111
+ let matchFinally = jest.fn();
112
+
113
+ class CustomError extends Error {
114
+ }
115
+
116
+ const result = $try(() => {
117
+ throw CustomError;
118
+ }).catch(CustomError, () => {
119
+ matchCustomError();
120
+ }).catch([TypeError, SyntaxError], (error) => {
121
+ matchArrayOfErrors(error);
122
+ }).other((error) => {
123
+ matchOther(error);
124
+ }).finally(({ value, error }) => {
125
+ matchFinally({ value, error });
126
+ });
127
+
128
+ expect(matchCustomError).toBeCalled();
129
+ expect(matchArrayOfErrors).not.toBeCalled();
130
+ expect(matchOther).not.toBeCalled();
131
+ expect(matchFinally).toBeCalled();
132
+ expect(result).toMatchObject({ error: CustomError, value: undefined });
133
+ });
184
134
 
185
- test('should be return result from `other` branch', () => {
186
- let matchCustomError = jest.fn();
187
- let matchArrayOfErrors = jest.fn();
188
- let matchOther = jest.fn();
189
- let matchFinally = jest.fn();
135
+ test('should be return result from `finally` branch without `other`', () => {
136
+ let matchCustomError = jest.fn();
137
+ let matchArrayOfErrors = jest.fn();
138
+ let matchOther = jest.fn();
139
+ let matchFinally = jest.fn();
140
+
141
+ class CustomError extends Error {
142
+ }
143
+
144
+ const result = $try(() => {
145
+ throw CustomError;
146
+ }).catch([TypeError, SyntaxError], (error) => {
147
+ matchArrayOfErrors(error);
148
+ }).finally(({ value, error }) => {
149
+ matchFinally({ value, error });
150
+ return value; // ?
151
+ });
152
+
153
+ expect(matchCustomError).not.toBeCalled();
154
+ expect(matchArrayOfErrors).not.toBeCalled();
155
+ expect(matchOther).not.toBeCalled();
156
+ expect(matchFinally).toBeCalled();
157
+ expect(result).toMatchObject({ error: CustomError, value: undefined });
158
+ });
190
159
 
191
- class CustomError extends Error {
192
- }
160
+ test('should be return result from `catch` branch', () => {
161
+ let matchCustomError = jest.fn();
162
+ let matchArrayOfErrors = jest.fn();
163
+ let matchOther = jest.fn();
164
+ let matchFinally = jest.fn();
165
+
166
+ class CustomError extends Error {
167
+ }
168
+
169
+ const result = $try(() => {
170
+ throw CustomError;
171
+ }).catch([TypeError, SyntaxError], (error) => {
172
+ matchArrayOfErrors(error);
173
+ });
174
+
175
+ expect(matchCustomError).not.toBeCalled();
176
+ expect(matchArrayOfErrors).not.toBeCalled();
177
+ expect(matchOther).not.toBeCalled();
178
+ expect(matchFinally).not.toBeCalled();
179
+ expect(result).toMatchObject({ error: CustomError, value: undefined });
180
+ });
193
181
 
194
- const result = $try(() => {
195
- throw CustomError;
196
- }).other((error) => {
197
- matchOther(error);
182
+ test('should be return result from `other` branch', () => {
183
+ let matchCustomError = jest.fn();
184
+ let matchArrayOfErrors = jest.fn();
185
+ let matchOther = jest.fn();
186
+ let matchFinally = jest.fn();
187
+
188
+ class CustomError extends Error {
189
+ }
190
+
191
+ const result = $try(() => {
192
+ throw CustomError;
193
+ }).other((error) => {
194
+ matchOther(error);
195
+ });
196
+
197
+ expect(matchCustomError).not.toBeCalled();
198
+ expect(matchArrayOfErrors).not.toBeCalled();
199
+ expect(matchOther).toBeCalledWith(CustomError);
200
+ expect(matchFinally).not.toBeCalled();
201
+ expect(result).toMatchObject({ error: CustomError, value: undefined });
198
202
  });
199
203
 
200
- expect(matchCustomError).not.toBeCalled();
201
- expect(matchArrayOfErrors).not.toBeCalled();
202
- expect(matchOther).toBeCalledWith(CustomError);
203
- expect(matchFinally).not.toBeCalled();
204
- expect(result).toMatchObject({ error: CustomError, result: undefined });
204
+ test('should be return result without branches', () => {
205
+ let matchCustomError = jest.fn();
206
+ let matchArrayOfErrors = jest.fn();
207
+ let matchOther = jest.fn();
208
+ let matchFinally = jest.fn();
209
+
210
+ const result = $try(() => {
211
+ throw SyntaxError;
212
+ });
213
+
214
+ expect(matchCustomError).not.toBeCalled();
215
+ expect(matchArrayOfErrors).not.toBeCalled();
216
+ expect(matchOther).not.toBeCalled();
217
+ expect(matchFinally).not.toBeCalled();
218
+ expect(result).toMatchObject({ error: SyntaxError, value: undefined });
219
+ });
205
220
  });
206
221
 
222
+ /**
223
+ * async tests
224
+ */
225
+ describe('promised version', () => {
226
+ test('resolve try', async () => {
227
+ let matchCustomError = jest.fn();
228
+ let matchArrayOfErrors = jest.fn();
229
+ let matchOther = jest.fn();
230
+ let matchFinally = jest.fn();
231
+
232
+ const result = $try(() => {
233
+ return Promise.resolve(42);
234
+ });
235
+
236
+ await result;
237
+
238
+ expect(matchCustomError).not.toBeCalled();
239
+ expect(matchArrayOfErrors).not.toBeCalled();
240
+ expect(matchOther).not.toBeCalled();
241
+ expect(matchFinally).not.toBeCalled();
242
+
243
+ expect(result).toBeInstanceOf(Promise);
244
+ expect(await result).toEqual({
245
+ value: 42,
246
+ error: undefined,
247
+ });
248
+ });
249
+ test('reject try', async () => {
250
+ let matchCustomError = jest.fn();
251
+ let matchArrayOfErrors = jest.fn();
252
+ let matchOther = jest.fn();
253
+ let matchFinally = jest.fn();
254
+
255
+ const result = $try(() => {
256
+ return Promise.reject(42);
257
+ });
258
+
259
+ expect(matchCustomError).not.toBeCalled();
260
+ expect(matchArrayOfErrors).not.toBeCalled();
261
+ expect(matchOther).not.toBeCalled();
262
+ expect(matchFinally).not.toBeCalled();
263
+
264
+ expect(result).toBeInstanceOf(Promise);
265
+ expect(await result).toEqual({
266
+ value: undefined,
267
+ error: 42,
268
+ });
269
+ });
270
+ test('throw try', async () => {
271
+ const result = $try(() => {
272
+ return new Promise(() => {
273
+ throw new Error('error');
274
+ });
275
+ });
276
+
277
+ expect(result).toBeInstanceOf(Promise);
278
+
279
+ expect(await result).toEqual({
280
+ value: undefined,
281
+ error: Error('error'),
282
+ });
283
+ });
207
284
 
208
- test('should be return result without branches', () => {
209
- let matchCustomError = jest.fn();
210
- let matchArrayOfErrors = jest.fn();
211
- let matchOther = jest.fn();
212
- let matchFinally = jest.fn();
285
+ test('resolve try.catch', async () => {
286
+ let matchError = jest.fn();
287
+ let matchSyntaxError = jest.fn();
288
+ let matchOther = jest.fn();
289
+
290
+ const result = $try(() => {
291
+ return Promise.resolve(42);
292
+ }).catch(Error, () => {
293
+ matchError();
294
+ }).catch(SyntaxError, () => {
295
+ matchSyntaxError();
296
+ }).other((error) => {
297
+ matchOther(error);
298
+ });
299
+
300
+ expect(matchError).not.toBeCalled();
301
+ expect(matchSyntaxError).not.toBeCalled();
302
+ expect(matchOther).not.toBeCalled();
303
+
304
+ expect(result).toBeInstanceOf(Promise);
305
+ expect(await result).toEqual({
306
+ value: 42,
307
+ error: undefined,
308
+ });
309
+ });
310
+ test('reject try.catch', async () => {
311
+ let matchError = jest.fn();
312
+ let matchOther = jest.fn();
313
+
314
+ const result = $try(() => {
315
+ return Promise.reject(123);
316
+ }).catch(Error, () => {
317
+ matchOther();
318
+ }).catch(123, () => {
319
+ matchError();
320
+ }).catch('error', () => {
321
+ matchOther();
322
+ });
323
+
324
+ await result; //?
325
+
326
+ expect(matchOther).not.toBeCalled();
327
+ expect(matchError).toBeCalled();
328
+
329
+ expect(result).toBeInstanceOf(Promise);
330
+ expect(await result).toEqual({
331
+ value: undefined,
332
+ error: 123,
333
+ });
334
+ });
335
+ test('throw try.catch', async () => {
336
+ let matchError = jest.fn();
337
+ let matchOther = jest.fn();
338
+
339
+ const result = $try(() => {
340
+ return new Promise(() => {
341
+ throw 'error';
342
+ });
343
+ }).catch(Error, () => {
344
+ matchOther();
345
+ }).catch(123, () => {
346
+ matchError();
347
+ }).catch('error', () => {
348
+ matchOther();
349
+ });
350
+
351
+ expect(result).toBeInstanceOf(Promise);
352
+ expect(await result).toEqual({
353
+ value: undefined,
354
+ error: 'error',
355
+ });
356
+
357
+ expect(matchOther).toBeCalledTimes(1);
358
+ expect(matchError).not.toBeCalled();
359
+ });
213
360
 
214
- const result = $try(() => {
215
- throw SyntaxError;
361
+ test('resolve try.other', async () => {
362
+ let matchCustomError = jest.fn();
363
+ let matchArrayOfErrors = jest.fn();
364
+ let matchOther = jest.fn();
365
+ let matchFinally = jest.fn();
366
+
367
+ const result = $try(() => {
368
+ return Promise.resolve('ok');
369
+ }).other(({ value, error }) => {
370
+ matchOther({ value, error });
371
+ });
372
+
373
+ expect(result).toBeInstanceOf(Promise);
374
+ expect(await result).toEqual({
375
+ value: 'ok',
376
+ error: undefined,
377
+ });
378
+
379
+ expect(matchCustomError).not.toBeCalled();
380
+ expect(matchArrayOfErrors).not.toBeCalled();
381
+ expect(matchOther).not.toBeCalled();
382
+ expect(matchFinally).not.toBeCalled();
383
+ });
384
+ test('reject try.other', async () => {
385
+ let matchError = jest.fn();
386
+ let matchOther = jest.fn();
387
+
388
+ const result = $try(() => {
389
+ return Promise.reject('error');
390
+ }).catch('error1', () => {
391
+ matchError();
392
+ }).catch('error2', () => {
393
+ matchError();
394
+ }).other((error) => {
395
+ matchOther(error);
396
+ });
397
+
398
+ expect(result).toBeInstanceOf(Promise);
399
+ expect(await result).toEqual({
400
+ value: undefined,
401
+ error: 'error',
402
+ });
403
+
404
+ expect(matchError).not.toBeCalled();
405
+ expect(matchOther).toBeCalledWith('error');
406
+ });
407
+ test('throw try.other', async () => {
408
+ let matchError = jest.fn();
409
+ let matchOther = jest.fn();
410
+
411
+ const result = $try(() => {
412
+ return new Promise(() => {
413
+ throw 'error';
414
+ });
415
+ }).catch('error1', () => {
416
+ matchError();
417
+ }).catch('error2', () => {
418
+ matchError();
419
+ }).other((error) => {
420
+ matchOther(error);
421
+ });
422
+
423
+ expect(result).toBeInstanceOf(Promise);
424
+ expect(await result).toEqual({
425
+ value: undefined,
426
+ error: 'error',
427
+ });
428
+
429
+ expect(matchError).not.toBeCalled();
430
+ expect(matchOther).toBeCalledWith('error');
216
431
  });
217
432
 
218
- expect(matchCustomError).not.toBeCalled();
219
- expect(matchArrayOfErrors).not.toBeCalled();
220
- expect(matchOther).not.toBeCalled();
221
- expect(matchFinally).not.toBeCalled();
222
- expect(result).toMatchObject({ error: SyntaxError, result: undefined });
433
+ test('when throw should be match array or exception', async () => {
434
+ let matchSingleError = jest.fn();
435
+ let matchArrayError = jest.fn();
436
+ let matchOther = jest.fn();
437
+ let matchFinally = jest.fn();
438
+
439
+ const attach = (ctx: PromisedTryReturn<any>) => {
440
+ return ctx.catch(SyntaxError, () => {
441
+ matchSingleError(SyntaxError);
442
+ }).catch([ReferenceError, SyntaxError], (error) => {
443
+ matchArrayError(error);
444
+ }).other((error) => {
445
+ matchOther(error);
446
+ }).finally(({ value, error }) => {
447
+ matchFinally({ value, error });
448
+ });
449
+ };
450
+
451
+ const testSingle = $try(() => new Promise(() => {
452
+ throw SyntaxError;
453
+ }));
454
+
455
+ const testArray = $try(() => new Promise(() => {
456
+ throw ReferenceError;
457
+ }));
458
+
459
+ const testOther = $try(() => new Promise(() => {
460
+ throw TypeError;
461
+ }));
462
+
463
+ const testResolve = $try(() => new Promise((resolve) => {
464
+ resolve('ok');
465
+ }));
466
+
467
+ const testReject = $try(() => new Promise((_, reject) => {
468
+ reject('reject');
469
+ }));
470
+
471
+ const resultSingle = attach(testSingle);
472
+ const resultArray = attach(testArray);
473
+ const resultOther = attach(testOther);
474
+ const resultResolve = attach(testResolve);
475
+ const resultReject = attach(testReject);
476
+
477
+ expect(resultSingle).toBeInstanceOf(Promise);
478
+ expect(resultArray).toBeInstanceOf(Promise);
479
+ expect(resultOther).toBeInstanceOf(Promise);
480
+ expect(resultResolve).toBeInstanceOf(Promise);
481
+ expect(resultReject).toBeInstanceOf(Promise);
482
+
483
+ expect(await resultSingle).toEqual({
484
+ value: undefined,
485
+ error: SyntaxError,
486
+ });
487
+ expect(await resultArray).toEqual({
488
+ value: undefined,
489
+ error: ReferenceError,
490
+ });
491
+ expect(await resultOther).toEqual({
492
+ value: undefined,
493
+ error: TypeError,
494
+ });
495
+ expect(await resultResolve).toEqual({
496
+ value: 'ok',
497
+ });
498
+ expect(await resultReject).toEqual({
499
+ error: 'reject',
500
+ });
501
+ });
223
502
  });
package/src/main.ts CHANGED
@@ -1,71 +1,127 @@
1
- export type ResultType<Rsult, ErrorType> = {
2
- result?: Rsult;
3
- error?: ErrorType;
4
- };
1
+ export type ErrrorHandler<ErrorType> = (error?: ErrorType) => void
5
2
 
6
- export type ErrrorHandler<ErrorType> = (error?: ErrorType) => void;
3
+ export type FinallyCallback<Result, ErrorType = any> = (params: ResultType<Result, ErrorType>) => void
7
4
 
8
- export type FinallyCallback<Result, ErrorType> = ((params: ResultType<Result, ErrorType>) => Result | void | undefined);
5
+ export type TryBody<Result> = () => Result | Promise<Result> | never
9
6
 
10
- export type TryReturn<Result, ErrorType = any> = {
11
- catch: (error: ErrorType | ErrorType[], handler: ErrrorHandler<ErrorType>) => TryReturn<Result, ErrorType>;
12
- other: (handler: ErrrorHandler<ErrorType>) => Pick<TryReturn<Result, ErrorType>, 'finally'>,
13
- finally: (callback?: FinallyCallback<Result, ErrorType>) => ResultType<Result, ErrorType>,
14
- result: Result,
15
- error: ErrorType
7
+ export type ResultType<Result, ErrorType = any> = {
8
+ value?: Result;
9
+ error?: ErrorType;
16
10
  }
17
11
 
18
- export type TryBody<Result> = () => Result | never;
12
+ export type FinallyReturn<Return, ErrorType = any> =
13
+ ResultType<Return, ErrorType>
14
+
15
+ export type OtherReturn<Return, ErrorType = any> =
16
+ FinallyReturn<Return, ErrorType> &
17
+ {
18
+ finally: (callback: FinallyCallback<Return, ErrorType>) => ResultType<Return, ErrorType>
19
+ }
20
+
21
+ export type CatchReturn<Return, ErrorType = any> =
22
+ FinallyReturn<Return, ErrorType> &
23
+ OtherReturn<Return, ErrorType> &
24
+ {
25
+ catch: (error: ErrorType | ErrorType[], handler: ErrrorHandler<ErrorType>) => TryReturn<Return, ErrorType>;
26
+ other: (handler: ErrrorHandler<ErrorType>) => Pick<TryReturn<Return, ErrorType>, 'finally' | 'value' | 'error'>,
27
+ }
28
+
29
+ export type TryReturn<Return, ErrorType = any> =
30
+ CatchReturn<Return, ErrorType>
19
31
 
20
- export function $try<Return>(body: TryBody<Return>): TryReturn<Return> {
32
+ export type PromisedTryReturn<Return> =
33
+ TryReturn<Return> |
34
+ (Promise<ResultType<Return>> & TryReturn<Return>)
35
+
36
+ export function $try<Return>(body: TryBody<Return>): PromisedTryReturn<Return> {
21
37
  let caught = false;
22
- let error: any | { constructor?: any; };
23
- let result: Return | any;
24
- const isSameInstance = (e1: any) => e1 === error || e1 === error?.constructor;
38
+ let error: any | { constructor?: any; } | Promise<any | { constructor?: any; }>;
39
+ let bodyResponse: Return | Promise<Return>;
40
+ let result: PromisedTryReturn<Return>;
25
41
 
26
- try {
27
- result = body();
28
- } catch (e) {
29
- error = e;
42
+ const isSameError = (e1: any, error: any) => e1 === error || e1 === error?.constructor;
43
+
44
+ function handleErrors(err: any[], err2: any, handler: { (error?: any): void; (error?: any): void; (): any }) {
45
+ if (isSameError(err, err2) || (Array.isArray(err) && err.some(e => isSameError(e, err2)))) {
46
+ handler(err2);
47
+ caught = true;
48
+ }
30
49
  }
31
50
 
32
- const chain: TryReturn<typeof result, typeof error> = {
51
+ function buildResult(br: typeof bodyResponse): ResultType<Return> | Promise<ResultType<Return>> {
52
+ if (br instanceof Promise) {
53
+ const bodyPromise = br as Promise<Return>;
54
+ return new Promise<ResultType<Return>>(async (resolve) => {
55
+ bodyPromise.then((response: any) => {
56
+ resolve({
57
+ value: response,
58
+ error: undefined,
59
+ });
60
+ }).catch((e: any) => {
61
+ resolve({
62
+ value: undefined,
63
+ error: e,
64
+ });
65
+ });
66
+ });
67
+ } else {
68
+ return {
69
+ value: br,
70
+ error: undefined,
71
+ };
72
+ }
73
+ }
74
+
75
+ const chain: TryReturn<Return, typeof error> = {
33
76
  catch: (err, handler) => {
34
- if (!err || !handler) {
35
- return chain;
77
+ if (result instanceof Promise) {
78
+ result.then((response) => {
79
+ typeof response.error !== 'undefined' && !caught && handleErrors(err, response.error, handler);
80
+ });
81
+ } else {
82
+ error && !caught && handleErrors(err, error, handler);
36
83
  }
37
- if (isSameInstance(err)) {
38
- handler && handler();
39
- caught = true;
40
- } else if (Array.isArray(err) && err.some(isSameInstance)) {
41
- handler && handler();
42
- caught = true;
43
- }
44
- return chain;
84
+ return result;
45
85
  },
46
86
 
47
- other: (handler) => {
48
- if (!caught && error) {
49
- handler && handler(error);
87
+ other: (callback) => {
88
+ if (result instanceof Promise) {
89
+ result.then((response) => {
90
+ typeof response.error !== 'undefined' && !caught && callback(response.error);
91
+ });
92
+ } else {
93
+ typeof result.error !== 'undefined' && !caught && callback && callback(result.error);
50
94
  }
51
- return {
52
- finally: chain.finally,
53
- result,
54
- error,
55
- };
95
+ return result;
56
96
  },
57
97
 
58
- finally: (callback?) => {
59
- return {
60
- result: callback ? callback({ result, error }) : result,
61
- error,
62
- };
98
+ finally: (callback) => {
99
+ if (result instanceof Promise) {
100
+ result.then((response) => {
101
+ callback(response);
102
+ });
103
+ } else {
104
+ callback({
105
+ value: result.value,
106
+ error: result.error,
107
+ });
108
+ }
109
+ return result;
63
110
  },
64
- result,
65
- error,
66
111
  };
67
112
 
68
- return chain;
113
+ try {
114
+ bodyResponse = body();
115
+ result = Object.assign(buildResult(bodyResponse), chain);
116
+ } catch (e) {
117
+ error = e;
118
+ result = Object.assign(chain, {
119
+ value: undefined,
120
+ error: e,
121
+ });
122
+ }
123
+
124
+ return result;
69
125
  }
70
126
 
71
127
  export default $try;