@alessiofrittoli/exception 1.1.0 → 1.2.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 +132 -12
- package/dist/code.d.mts +14 -0
- package/dist/code.d.ts +14 -0
- package/dist/code.js +1 -0
- package/dist/code.mjs +1 -0
- package/dist/index.d.mts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +21 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Exception 🚦
|
|
2
2
|
|
|
3
|
-
Version 1.
|
|
3
|
+
Version 1.2.0
|
|
4
4
|
|
|
5
5
|
## Handle errors with ease
|
|
6
6
|
|
|
@@ -80,7 +80,7 @@ import Exception from '@alessiofrittoli/exception'
|
|
|
80
80
|
|
|
81
81
|
try {
|
|
82
82
|
throw new Exception( 'Resource not found', {
|
|
83
|
-
code : '
|
|
83
|
+
code : 'ERR:NOTFOUND',
|
|
84
84
|
status : 404,
|
|
85
85
|
} )
|
|
86
86
|
} catch ( error ) {
|
|
@@ -94,11 +94,13 @@ try {
|
|
|
94
94
|
|
|
95
95
|
A utility method to check if an object is an instance of the `Exception` class.
|
|
96
96
|
|
|
97
|
+
It supports also a JSON representation of the `Exception` class (commonly returned by server responses).
|
|
98
|
+
|
|
97
99
|
###### Example
|
|
98
100
|
|
|
99
101
|
```ts
|
|
100
102
|
try {
|
|
101
|
-
throw new Exception( 'Something went wrong', { code: '
|
|
103
|
+
throw new Exception( 'Something went wrong', { code: 'ERR:UNKNOWN' } )
|
|
102
104
|
} catch ( error ) {
|
|
103
105
|
if ( Exception.isException( error ) ) {
|
|
104
106
|
// we can safely access `Exception` properties
|
|
@@ -109,6 +111,18 @@ try {
|
|
|
109
111
|
}
|
|
110
112
|
```
|
|
111
113
|
|
|
114
|
+
```ts
|
|
115
|
+
/** Simulates JSON Exception returned by a server JSON Response. */
|
|
116
|
+
const error = (
|
|
117
|
+
JSON.parse( JSON.stringify( new Exception( 'Exception with custom name.', {
|
|
118
|
+
code: 0,
|
|
119
|
+
name: 'AbortError',
|
|
120
|
+
} ) ) )
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
console.log( Exception.isException( error ) ) // Outputs: true
|
|
124
|
+
```
|
|
125
|
+
|
|
112
126
|
---
|
|
113
127
|
|
|
114
128
|
#### Usage Scenarios
|
|
@@ -120,25 +134,121 @@ The `Exception` class is ideal for creating domain-specific errors with addition
|
|
|
120
134
|
###### Example
|
|
121
135
|
|
|
122
136
|
```ts
|
|
123
|
-
|
|
137
|
+
try {
|
|
138
|
+
await fetch( ... )
|
|
139
|
+
} catch ( error ) {
|
|
140
|
+
// error thrown by the server: Exception( 'Wrong value.', { code: ErrorCode.WRONG_VALUE, status: 422 } )
|
|
141
|
+
if ( Exception.isException( error ) ) {
|
|
142
|
+
console.log( error.code ) // `error.code` is type of `ErrorCode`.
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
#### `ErrorCode` enum
|
|
150
|
+
|
|
151
|
+
The `ErrorCode` enum is a utility that provides pre-defined constants for the most common error codes.\
|
|
152
|
+
It is designed to simplify error handling and improve feedback quality returned to the user.
|
|
153
|
+
|
|
154
|
+
<details>
|
|
155
|
+
|
|
156
|
+
<summary>Constants Overview</summary>
|
|
157
|
+
|
|
158
|
+
| Constant | Value | Description |
|
|
159
|
+
|---------------|------------------|---------------------------------------------------------|
|
|
160
|
+
| `UNKNOWN` | `ERR:UNKNOWN` | Returned when an unexpected error occured. |
|
|
161
|
+
| `ABORT` | `ERR:ABORT` | Returned when user abort the request. |
|
|
162
|
+
| `EMPTY_VALUE` | `ERR:EMPTYVALUE` | Returned when a required value is "falsy". |
|
|
163
|
+
| `WRONG_VALUE` | `ERR:WRONGVALUE` | Return when a required value is not the expected value. |
|
|
164
|
+
| `EXPIRED` | `ERR:EXPIRED` | Returned when a requested has been performed too late. |
|
|
165
|
+
| `TOO_EARLY` | `ERR:TOOEARLY` | Returned when a request has been performed too early. |
|
|
166
|
+
|
|
167
|
+
</details>
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
<details>
|
|
172
|
+
|
|
173
|
+
<summary>Extending the `enum` in your project</summary>
|
|
174
|
+
|
|
175
|
+
For obvious reasons the default `ErrorCode` provided by this library might be not enough to cover all the error cases in your project.
|
|
176
|
+
|
|
177
|
+
To fill this gap, you can "extend" the `ErrorCode` enum by doing so:
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
// myproject/src/error-code.ts
|
|
181
|
+
import ExceptionCode from '@alessiofrittoli/exception/code'
|
|
182
|
+
|
|
183
|
+
/** Your project custom `ErrorCode`. */
|
|
184
|
+
export enum MyProjectErrorCode
|
|
124
185
|
{
|
|
125
|
-
|
|
126
|
-
WRONG_FORMAT= 'ERRWRONGFORMAT',
|
|
127
|
-
EXPIRED = 'ERREXPIRED',
|
|
128
|
-
TOO_EARLY = 'ERRTOOEARLY',
|
|
129
|
-
NOT_ALLOWED = 'ERRNOTALLOWED',
|
|
186
|
+
INVALID_SIGN = 'ERR:INVALIDSIGN',
|
|
130
187
|
}
|
|
131
188
|
|
|
189
|
+
const ErrorCode = { ExceptionCode, MyProjectErrorCode }
|
|
190
|
+
type ErrorCode = MergedEnumValue<typeof ErrorCode>
|
|
191
|
+
|
|
192
|
+
export default ErrorCode
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
⚠️ The Type `MergedEnumValue<T>` is globally delcared from `@alessiofrittoli/type-utils` so make sure to install it if needed.
|
|
196
|
+
|
|
197
|
+
</details>
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
<details>
|
|
202
|
+
|
|
203
|
+
<summary>Usage</summary>
|
|
204
|
+
|
|
205
|
+
#### Using the default `ErrorCode` to throw a new `Exception`
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
import Exception from '@alessiofrittoli/exception'
|
|
209
|
+
import ErrorCode from '@alessiofrittoli/exception/code'
|
|
210
|
+
|
|
211
|
+
throw new Exception( 'Password is a required field to log you in.', {
|
|
212
|
+
code : ErrorCode.EMPTY_VALUE,
|
|
213
|
+
status : 422,
|
|
214
|
+
} )
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### Using custom `ErrorCode` to throw a new `Exception`
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
import Exception from '@alessiofrittoli/exception'
|
|
221
|
+
import ErrorCode from '@/error-code' // previously created in `myproject/src/error-code.ts`
|
|
222
|
+
|
|
223
|
+
throw new Exception( 'Invalid signature.', {
|
|
224
|
+
code : ErrorCode.MyProjectErrorCode.INVALID_SIGN,
|
|
225
|
+
status : 403,
|
|
226
|
+
} )
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
#### Using `ErrorCode` to handle errors
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
import ErrorCode from '@/error-code' // previously created in `myproject/src/error-code.ts`
|
|
233
|
+
|
|
132
234
|
try {
|
|
133
|
-
|
|
235
|
+
...
|
|
134
236
|
} catch ( error ) {
|
|
135
|
-
// error thrown by the server: Exception( 'Wrong value.', { code: ErrorCode.WRONG_FORMAT, status: 422 } )
|
|
136
237
|
if ( Exception.isException<string, ErrorCode>( error ) ) {
|
|
137
|
-
|
|
238
|
+
switch ( error.code ) { // `error.code` is now type of `ErrorCode` (custom).
|
|
239
|
+
case ErrorCode.MyProjectErrorCode.INVALID_SIGN:
|
|
240
|
+
console.log( 'The signature is not valid.' )
|
|
241
|
+
break
|
|
242
|
+
case ErrorCode.ExceptionCode.UNKNOWN:
|
|
243
|
+
default:
|
|
244
|
+
console.log( 'Unexpected error occured.' )
|
|
245
|
+
}
|
|
138
246
|
}
|
|
139
247
|
}
|
|
140
248
|
```
|
|
141
249
|
|
|
250
|
+
</details>
|
|
251
|
+
|
|
142
252
|
---
|
|
143
253
|
|
|
144
254
|
### Development
|
|
@@ -196,6 +306,16 @@ pnpm test:jest
|
|
|
196
306
|
pnpm test:jest:jsdom
|
|
197
307
|
```
|
|
198
308
|
|
|
309
|
+
Run tests with coverage.
|
|
310
|
+
|
|
311
|
+
An HTTP server is then started to serve coverage files from `./coverage` folder.
|
|
312
|
+
|
|
313
|
+
⚠️ You may see a blank page the first time you run this command. Simply refresh the browser to see the updates.
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
pnpm test:coverage
|
|
317
|
+
```
|
|
318
|
+
|
|
199
319
|
---
|
|
200
320
|
|
|
201
321
|
### Contributing
|
package/dist/code.d.mts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Most common error codes.
|
|
3
|
+
*
|
|
4
|
+
*/
|
|
5
|
+
declare enum ErrorCode {
|
|
6
|
+
UNKNOWN = "ERR:UNKNOWN",
|
|
7
|
+
ABORT = "ERR:ABORT",
|
|
8
|
+
EMPTY_VALUE = "ERR:EMPTYVALUE",
|
|
9
|
+
WRONG_VALUE = "ERR:WRONGVALUE",
|
|
10
|
+
EXPIRED = "ERR:EXPIRED",
|
|
11
|
+
TOO_EARLY = "ERR:TOOEARLY"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { ErrorCode as default };
|
package/dist/code.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Most common error codes.
|
|
3
|
+
*
|
|
4
|
+
*/
|
|
5
|
+
declare enum ErrorCode {
|
|
6
|
+
UNKNOWN = "ERR:UNKNOWN",
|
|
7
|
+
ABORT = "ERR:ABORT",
|
|
8
|
+
EMPTY_VALUE = "ERR:EMPTYVALUE",
|
|
9
|
+
WRONG_VALUE = "ERR:WRONGVALUE",
|
|
10
|
+
EXPIRED = "ERR:EXPIRED",
|
|
11
|
+
TOO_EARLY = "ERR:TOOEARLY"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { ErrorCode as default };
|
package/dist/code.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var E=(R=>(R.UNKNOWN="ERR:UNKNOWN",R.ABORT="ERR:ABORT",R.EMPTY_VALUE="ERR:EMPTYVALUE",R.WRONG_VALUE="ERR:WRONGVALUE",R.EXPIRED="ERR:EXPIRED",R.TOO_EARLY="ERR:TOOEARLY",R))(E||{}),A=E;module.exports=A;
|
package/dist/code.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var E=(R=>(R.UNKNOWN="ERR:UNKNOWN",R.ABORT="ERR:ABORT",R.EMPTY_VALUE="ERR:EMPTYVALUE",R.WRONG_VALUE="ERR:WRONGVALUE",R.EXPIRED="ERR:EXPIRED",R.TOO_EARLY="ERR:TOOEARLY",R))(E||{}),N=E;export{N as default};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
import ErrorCode from './code.mjs';
|
|
2
|
+
|
|
3
|
+
interface ExceptionOptions<TCode = ErrorCode> extends ErrorOptions {
|
|
2
4
|
code: TCode;
|
|
3
5
|
name?: string;
|
|
4
6
|
status?: number;
|
|
5
7
|
}
|
|
6
|
-
declare class Exception<TMessage = string, TCode =
|
|
8
|
+
declare class Exception<TMessage = string, TCode = ErrorCode> extends Error implements ExceptionOptions<TCode> {
|
|
7
9
|
message: TMessage;
|
|
8
10
|
status: number | undefined;
|
|
9
11
|
name: string;
|
|
10
12
|
typename: 'Exception';
|
|
11
13
|
code: TCode;
|
|
12
14
|
constructor(message: TMessage, options: ExceptionOptions<TCode>);
|
|
13
|
-
static isException<TMessage = string, TCode =
|
|
15
|
+
static isException<TMessage = string, TCode = ErrorCode>(error: any): error is Exception<TMessage, TCode>;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export { type ExceptionOptions, Exception as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
import ErrorCode from './code.js';
|
|
2
|
+
|
|
3
|
+
interface ExceptionOptions<TCode = ErrorCode> extends ErrorOptions {
|
|
2
4
|
code: TCode;
|
|
3
5
|
name?: string;
|
|
4
6
|
status?: number;
|
|
5
7
|
}
|
|
6
|
-
declare class Exception<TMessage = string, TCode =
|
|
8
|
+
declare class Exception<TMessage = string, TCode = ErrorCode> extends Error implements ExceptionOptions<TCode> {
|
|
7
9
|
message: TMessage;
|
|
8
10
|
status: number | undefined;
|
|
9
11
|
name: string;
|
|
10
12
|
typename: 'Exception';
|
|
11
13
|
code: TCode;
|
|
12
14
|
constructor(message: TMessage, options: ExceptionOptions<TCode>);
|
|
13
|
-
static isException<TMessage = string, TCode =
|
|
15
|
+
static isException<TMessage = string, TCode = ErrorCode>(error: any): error is Exception<TMessage, TCode>;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export { type ExceptionOptions, Exception as default };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var s=class
|
|
1
|
+
'use strict';var s=class o extends Error{message;status;name;typename;code;constructor(e,t){super("",t),this.typename="Exception",this.name=t.name||this.typename,this.message=e,this.code=t.code,this.status=t.status;}static isException(e){return e instanceof o||typeof e=="object"&&"typename"in e&&e.typename==="Exception"}},a=s;module.exports=a;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var s=class
|
|
1
|
+
var s=class o extends Error{message;status;name;typename;code;constructor(e,t){super("",t),this.typename="Exception",this.name=t.name||this.typename,this.message=e,this.code=t.code,this.status=t.status;}static isException(e){return e instanceof o||typeof e=="object"&&"typename"in e&&e.typename==="Exception"}},r=s;export{r as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alessiofrittoli/exception",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Handle errors with ease",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Alessio Frittoli",
|
|
@@ -27,14 +27,28 @@
|
|
|
27
27
|
"files": [
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"import": "./dist/index.mjs",
|
|
33
|
+
"require": "./dist/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./code": {
|
|
36
|
+
"types": "./dist/code.d.ts",
|
|
37
|
+
"import": "./dist/code.mjs",
|
|
38
|
+
"require": "./dist/code.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
30
41
|
"sideEffects": false,
|
|
31
42
|
"scripts": {
|
|
32
|
-
"build": "
|
|
43
|
+
"build": "pnpm lint && pnpm test:ci && tsup",
|
|
33
44
|
"lint": "eslint",
|
|
34
45
|
"test": "jest --watchAll --verbose",
|
|
35
46
|
"test:jsdom": "JSDOM=true pnpm test",
|
|
36
47
|
"test:ci": "jest --ci --verbose",
|
|
37
48
|
"test:ci:jsdom": "JSDOM=true pnpm test:ci",
|
|
49
|
+
"test:serve-coverage": "http-server ./coverage/lcov-report --gzip true -p 0 -o --silent",
|
|
50
|
+
"test:coverage": "concurrently --prefix none --kill-others \"pnpm jest --watchAll --verbose --coverage\" \"pnpm test:serve-coverage\"",
|
|
51
|
+
"test:coverage:jsdom": "JSDOM=true pnpm test:coverage",
|
|
38
52
|
"test:jest": "pnpm test jest.test.ts",
|
|
39
53
|
"test:jest:jsdom": "JSDOM=true pnpm test:jest",
|
|
40
54
|
"test:exception": "pnpm test exception.test.ts"
|
|
@@ -44,15 +58,18 @@
|
|
|
44
58
|
"@jest/globals": "^29.7.0",
|
|
45
59
|
"@types/jest": "^29.5.14",
|
|
46
60
|
"@types/node": "^22.10.2",
|
|
61
|
+
"concurrently": "^9.1.0",
|
|
47
62
|
"dotenv": "^16.4.7",
|
|
63
|
+
"esbuild": "0.24.0",
|
|
48
64
|
"eslint": "^9.17.0",
|
|
49
|
-
"globals": "^15.
|
|
65
|
+
"globals": "^15.14.0",
|
|
66
|
+
"http-server": "^14.1.1",
|
|
50
67
|
"jest": "^29.7.0",
|
|
51
68
|
"jest-environment-jsdom": "^29.7.0",
|
|
52
69
|
"ts-jest": "^29.2.5",
|
|
53
70
|
"ts-node": "^10.9.2",
|
|
54
71
|
"tsup": "^8.3.5",
|
|
55
72
|
"typescript": "^5.7.2",
|
|
56
|
-
"typescript-eslint": "^8.18.
|
|
73
|
+
"typescript-eslint": "^8.18.1"
|
|
57
74
|
}
|
|
58
75
|
}
|