catch-match 1.1.0 → 2.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/README.md +27 -53
- package/jest.config.js +10 -0
- package/package.json +18 -5
- package/src/__tests__/main.test.ts +226 -0
- package/src/main.ts +42 -22
- package/tsconfig.json +2 -2
- package/tsconfig.test.json +3 -0
package/README.md
CHANGED
@@ -50,77 +50,51 @@ npm install catch-match
|
|
50
50
|
```
|
51
51
|
|
52
52
|
```javascript
|
53
|
-
import
|
53
|
+
import $try from 'catch-match';
|
54
54
|
// or
|
55
|
-
import {
|
56
|
-
// or
|
57
|
-
import { _try as customTry } from 'catch-match';
|
55
|
+
import { $try } from 'catch-match';
|
58
56
|
```
|
59
57
|
|
60
58
|
## Example 1
|
59
|
+
|
61
60
|
```javascript
|
62
|
-
const result =
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
}).catch(SyntaxError, (
|
67
|
-
|
68
|
-
}).
|
69
|
-
|
70
|
-
}).
|
71
|
-
|
72
|
-
}).finally(({value, context, error}) => {
|
73
|
-
// value: [1, 2, 3, 4, 5]
|
74
|
-
// context: {tmp: 'any context data'}
|
75
|
-
// error: undefined
|
76
|
-
if (!error) {
|
77
|
-
return value.reverse();
|
78
|
-
}
|
61
|
+
const result = $try(() => {
|
62
|
+
throw SyntaxError;
|
63
|
+
}).catch(ReferenceError, () => {
|
64
|
+
// noop
|
65
|
+
}).catch([TypeError, SyntaxError], () => {
|
66
|
+
// to be called
|
67
|
+
}).other((error) => {
|
68
|
+
// noop
|
69
|
+
}).finally(({ result, error }) => {
|
70
|
+
return result;
|
79
71
|
});
|
80
72
|
|
81
|
-
console.log(result);
|
82
|
-
// {
|
83
|
-
// value: [5, 4, 3, 2, 1]
|
84
|
-
// context: {tmp: 'any context data'}
|
85
|
-
// error: undefined
|
86
|
-
// }
|
87
|
-
|
73
|
+
console.log(result); // { error: SyntaxError, result: undefined }
|
88
74
|
```
|
89
75
|
|
90
76
|
## Example 2
|
77
|
+
|
91
78
|
```javascript
|
92
|
-
const result =
|
93
|
-
|
94
|
-
|
95
|
-
// ...
|
96
|
-
throw ReferenceError;
|
97
|
-
}).catch(SyntaxError, (context) => {
|
79
|
+
const result = $try(() => {
|
80
|
+
return [1, 2, 3];
|
81
|
+
}).catch(ReferenceError, () => {
|
98
82
|
// noop
|
99
|
-
}).catch([TypeError,
|
100
|
-
//
|
101
|
-
}).other((error
|
83
|
+
}).catch([TypeError, SyntaxError], () => {
|
84
|
+
// to be called
|
85
|
+
}).other((error) => {
|
102
86
|
// noop
|
103
|
-
}).finally(({
|
104
|
-
|
105
|
-
// context: {tmp: 'any context data'}
|
106
|
-
// error: ReferenceError
|
107
|
-
if (!error) {
|
108
|
-
return value.reverse();
|
109
|
-
}
|
87
|
+
}).finally(({ result, error }) => {
|
88
|
+
return result;
|
110
89
|
});
|
111
90
|
|
112
|
-
console.log(result);
|
113
|
-
// {
|
114
|
-
// value: undefined
|
115
|
-
// context: {tmp: 'any context data'}
|
116
|
-
// error: ReferenceError
|
117
|
-
// }
|
118
|
-
|
91
|
+
console.log(result); // {error: undefined, result: [1, 2, 3]}
|
119
92
|
```
|
120
93
|
|
121
94
|
## Example 3
|
95
|
+
|
122
96
|
```javascript
|
123
|
-
const result =
|
97
|
+
const result = $try(context => {
|
124
98
|
context.tmp = 'any context data';
|
125
99
|
console.log('start', context);
|
126
100
|
// ...
|
@@ -140,7 +114,7 @@ const result = _try(context => {
|
|
140
114
|
}
|
141
115
|
});
|
142
116
|
|
143
|
-
console.log(result);
|
117
|
+
console.log(result);
|
144
118
|
// {
|
145
119
|
// value: undefined
|
146
120
|
// context: {tmp: 'any context data', unexpectedError: true}
|
package/jest.config.js
ADDED
package/package.json
CHANGED
@@ -1,16 +1,29 @@
|
|
1
1
|
{
|
2
2
|
"name": "catch-match",
|
3
|
-
"version": "
|
3
|
+
"version": "2.0.0",
|
4
4
|
"repository": {
|
5
5
|
"url": "https://github.com/kobzarvs/catch-match"
|
6
6
|
},
|
7
|
-
"keywords": [
|
8
|
-
|
7
|
+
"keywords": [
|
8
|
+
"try",
|
9
|
+
"catch",
|
10
|
+
"match",
|
11
|
+
"pattern",
|
12
|
+
"errors",
|
13
|
+
"exceptions",
|
14
|
+
"throw",
|
15
|
+
"finally"
|
16
|
+
],
|
9
17
|
"main": "dist/main.js",
|
10
18
|
"scripts": {
|
11
|
-
"build": "tsc"
|
19
|
+
"build": "tsc",
|
20
|
+
"test": "jest"
|
21
|
+
},
|
22
|
+
"devDependencies": {
|
23
|
+
"@types/jest": "^27.4.0",
|
24
|
+
"jest": "^27.4.7",
|
25
|
+
"ts-jest": "^27.1.3"
|
12
26
|
},
|
13
|
-
"devDependencies": {},
|
14
27
|
"dependencies": {
|
15
28
|
"typescript": "^4.5.4"
|
16
29
|
}
|
@@ -0,0 +1,226 @@
|
|
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();
|
167
|
+
|
168
|
+
class CustomError extends Error {
|
169
|
+
}
|
170
|
+
|
171
|
+
const result = $try(() => {
|
172
|
+
throw CustomError;
|
173
|
+
}).catch([TypeError, SyntaxError], () => {
|
174
|
+
matchArrayOfErrors();
|
175
|
+
});
|
176
|
+
|
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
|
+
});
|
183
|
+
|
184
|
+
|
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();
|
190
|
+
|
191
|
+
class CustomError extends Error {
|
192
|
+
}
|
193
|
+
|
194
|
+
const result = $try(() => {
|
195
|
+
throw CustomError;
|
196
|
+
}).other((error) => {
|
197
|
+
matchOther(error);
|
198
|
+
});
|
199
|
+
|
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 });
|
205
|
+
});
|
206
|
+
|
207
|
+
|
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();
|
213
|
+
|
214
|
+
class CustomError extends Error {
|
215
|
+
}
|
216
|
+
|
217
|
+
const result = $try(() => {
|
218
|
+
throw CustomError;
|
219
|
+
});
|
220
|
+
|
221
|
+
expect(matchCustomError).not.toBeCalled();
|
222
|
+
expect(matchArrayOfErrors).not.toBeCalled();
|
223
|
+
expect(matchOther).not.toBeCalled();
|
224
|
+
expect(matchFinally).not.toBeCalled();
|
225
|
+
expect(result).toMatchObject({ error: CustomError, result: undefined });
|
226
|
+
});
|
package/src/main.ts
CHANGED
@@ -1,51 +1,71 @@
|
|
1
|
-
type
|
2
|
-
|
3
|
-
error?:
|
4
|
-
context?: any;
|
1
|
+
export type ResultType<Rsult, ErrorType> = {
|
2
|
+
result?: Rsult;
|
3
|
+
error?: ErrorType;
|
5
4
|
};
|
6
5
|
|
7
|
-
export
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
export type ErrrorHandler<ErrorType> = (error?: ErrorType) => void;
|
7
|
+
|
8
|
+
export type FinallyCallback<Result, ErrorType> = ((params: ResultType<Result, ErrorType>) => Result | void | undefined);
|
9
|
+
|
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
|
16
|
+
}
|
17
|
+
|
18
|
+
export type TryBody<Result> = () => Result | never;
|
19
|
+
|
20
|
+
export function $try<Return>(body: TryBody<Return>): TryReturn<Return> {
|
21
|
+
let caught = false;
|
22
|
+
let error: any | { constructor?: any; };
|
23
|
+
let result: Return | any;
|
11
24
|
const isSameInstance = (e1: any) => e1 === error || e1 === error?.constructor;
|
12
25
|
|
13
26
|
try {
|
14
|
-
result = body(
|
27
|
+
result = body();
|
15
28
|
} catch (e) {
|
16
29
|
error = e;
|
17
30
|
}
|
18
31
|
|
19
|
-
const chain = {
|
20
|
-
catch: (err
|
32
|
+
const chain: TryReturn<typeof result, typeof error> = {
|
33
|
+
catch: (err, handler) => {
|
21
34
|
if (!err || !handler) {
|
22
35
|
return chain;
|
23
36
|
}
|
24
37
|
if (isSameInstance(err)) {
|
25
|
-
handler && handler(
|
26
|
-
|
27
|
-
|
38
|
+
handler && handler();
|
39
|
+
caught = true;
|
40
|
+
} else if (Array.isArray(err) && err.some(isSameInstance)) {
|
41
|
+
handler && handler();
|
42
|
+
caught = true;
|
28
43
|
}
|
29
44
|
return chain;
|
30
45
|
},
|
31
|
-
|
32
|
-
|
33
|
-
|
46
|
+
|
47
|
+
other: (handler) => {
|
48
|
+
if (!caught && error) {
|
49
|
+
handler && handler(error);
|
34
50
|
}
|
35
51
|
return {
|
36
|
-
finally: chain.finally
|
52
|
+
finally: chain.finally,
|
53
|
+
result,
|
54
|
+
error,
|
37
55
|
};
|
38
56
|
},
|
39
|
-
|
57
|
+
|
58
|
+
finally: (callback?) => {
|
40
59
|
return {
|
41
|
-
|
60
|
+
result: callback ? callback({ result, error }) : result,
|
42
61
|
error,
|
43
|
-
context,
|
44
62
|
};
|
45
63
|
},
|
64
|
+
result,
|
65
|
+
error,
|
46
66
|
};
|
47
67
|
|
48
68
|
return chain;
|
49
69
|
}
|
50
70
|
|
51
|
-
export default
|
71
|
+
export default $try;
|
package/tsconfig.json
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
"target": "es6",
|
4
4
|
"useDefineForClassFields": true,
|
5
5
|
"module": "ESNext",
|
6
|
-
"lib": ["ESNext"],
|
6
|
+
"lib": ["ESNext", "DOM"],
|
7
7
|
"moduleResolution": "Node",
|
8
8
|
"strict": true,
|
9
9
|
"sourceMap": true,
|
@@ -15,7 +15,7 @@
|
|
15
15
|
"noUnusedParameters": true,
|
16
16
|
"noImplicitReturns": true,
|
17
17
|
"alwaysStrict": true,
|
18
|
-
"outDir": "dist"
|
18
|
+
"outDir": "dist",
|
19
19
|
},
|
20
20
|
"include": ["./src"]
|
21
21
|
}
|