@ooneex/exception 0.0.1 → 0.0.5
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 +193 -282
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +11 -6
- package/dist/ooneex-exception-0.0.1.tgz +0 -0
package/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# @ooneex/exception
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A type-safe exception handling library with HTTP status code integration for structured error management. This package provides a base `Exception` class and specialized exception types for common HTTP error scenarios with rich metadata including timestamps, status codes, and structured stack traces.
|
|
4
4
|
|
|
5
|
-

|
|
6
5
|

|
|
7
6
|

|
|
8
7
|

|
|
@@ -11,21 +10,19 @@ A comprehensive TypeScript/JavaScript library for creating structured, HTTP stat
|
|
|
11
10
|
|
|
12
11
|
## Features
|
|
13
12
|
|
|
14
|
-
✅ **HTTP Status Integration** - Built-in support for HTTP status codes
|
|
13
|
+
✅ **HTTP Status Integration** - Built-in support for all HTTP status codes
|
|
15
14
|
|
|
16
|
-
✅ **
|
|
15
|
+
✅ **Structured Stack Traces** - Parse stack traces into JSON for logging and debugging
|
|
17
16
|
|
|
18
|
-
✅ **
|
|
17
|
+
✅ **Rich Metadata** - Include timestamps, custom data, and original errors
|
|
19
18
|
|
|
20
|
-
✅ **
|
|
19
|
+
✅ **Specialized Exceptions** - Pre-built exceptions for common HTTP errors
|
|
21
20
|
|
|
22
|
-
✅ **
|
|
21
|
+
✅ **Type-Safe** - Full TypeScript support with proper type definitions
|
|
23
22
|
|
|
24
|
-
✅ **
|
|
23
|
+
✅ **Immutable Data** - Exception data is frozen after creation
|
|
25
24
|
|
|
26
|
-
✅ **
|
|
27
|
-
|
|
28
|
-
✅ **Error Wrapping** - Wrap native Error objects with additional context
|
|
25
|
+
✅ **Native Error Wrapping** - Wrap native JavaScript errors while preserving context
|
|
29
26
|
|
|
30
27
|
## Installation
|
|
31
28
|
|
|
@@ -51,290 +48,213 @@ npm install @ooneex/exception
|
|
|
51
48
|
|
|
52
49
|
## Usage
|
|
53
50
|
|
|
54
|
-
### Basic
|
|
51
|
+
### Basic Exception
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { Exception } from '@ooneex/exception';
|
|
55
|
+
|
|
56
|
+
throw new Exception('Something went wrong');
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### With HTTP Status Code
|
|
55
60
|
|
|
56
61
|
```typescript
|
|
57
62
|
import { Exception } from '@ooneex/exception';
|
|
63
|
+
import { HttpStatus } from '@ooneex/http-status';
|
|
64
|
+
|
|
65
|
+
throw new Exception('Resource not found', {
|
|
66
|
+
status: HttpStatus.Code.NotFound
|
|
67
|
+
});
|
|
68
|
+
```
|
|
58
69
|
|
|
59
|
-
|
|
60
|
-
const exception = new Exception('Something went wrong');
|
|
70
|
+
### With Custom Data
|
|
61
71
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
console.log(exception.date); // Date object
|
|
72
|
+
```typescript
|
|
73
|
+
import { Exception } from '@ooneex/exception';
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
status: 404,
|
|
75
|
+
throw new Exception('Validation failed', {
|
|
76
|
+
status: 400,
|
|
69
77
|
data: {
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
field: 'email',
|
|
79
|
+
value: 'invalid-email',
|
|
80
|
+
constraint: 'Must be a valid email address'
|
|
72
81
|
}
|
|
73
82
|
});
|
|
74
|
-
|
|
75
|
-
console.log(detailedException.status); // 404
|
|
76
|
-
console.log(detailedException.data); // { userId: 123, searchCriteria: {...} }
|
|
77
83
|
```
|
|
78
84
|
|
|
79
|
-
###
|
|
85
|
+
### Specialized Exceptions
|
|
80
86
|
|
|
81
87
|
```typescript
|
|
82
88
|
import {
|
|
89
|
+
NotFoundException,
|
|
83
90
|
BadRequestException,
|
|
84
91
|
UnauthorizedException,
|
|
85
|
-
NotFoundException,
|
|
86
92
|
MethodNotAllowedException
|
|
87
93
|
} from '@ooneex/exception';
|
|
88
94
|
|
|
89
|
-
//
|
|
90
|
-
throw new
|
|
91
|
-
|
|
92
|
-
value: 'invalid-email',
|
|
93
|
-
rule: 'Must be a valid email address'
|
|
95
|
+
// 404 Not Found
|
|
96
|
+
throw new NotFoundException('User not found', {
|
|
97
|
+
data: { userId: '123' }
|
|
94
98
|
});
|
|
95
99
|
|
|
96
|
-
//
|
|
97
|
-
throw new
|
|
98
|
-
|
|
99
|
-
expiredAt: new Date()
|
|
100
|
+
// 400 Bad Request
|
|
101
|
+
throw new BadRequestException('Invalid input', {
|
|
102
|
+
data: { errors: ['email is required', 'name is too short'] }
|
|
100
103
|
});
|
|
101
104
|
|
|
102
|
-
//
|
|
103
|
-
throw new
|
|
104
|
-
resourceType: 'User',
|
|
105
|
-
id: 123
|
|
106
|
-
});
|
|
105
|
+
// 401 Unauthorized
|
|
106
|
+
throw new UnauthorizedException('Invalid credentials');
|
|
107
107
|
|
|
108
108
|
// 405 Method Not Allowed
|
|
109
|
-
throw new MethodNotAllowedException('POST not allowed on this endpoint'
|
|
110
|
-
method: 'POST',
|
|
111
|
-
allowedMethods: ['GET', 'PUT']
|
|
112
|
-
});
|
|
109
|
+
throw new MethodNotAllowedException('POST method not allowed on this endpoint');
|
|
113
110
|
```
|
|
114
111
|
|
|
115
|
-
###
|
|
112
|
+
### Wrapping Native Errors
|
|
116
113
|
|
|
117
114
|
```typescript
|
|
118
115
|
import { Exception } from '@ooneex/exception';
|
|
119
116
|
|
|
120
117
|
try {
|
|
121
|
-
// Some operation that might fail
|
|
122
118
|
JSON.parse('invalid json');
|
|
123
119
|
} catch (error) {
|
|
124
|
-
// Wrap the native error with additional context
|
|
125
120
|
throw new Exception(error as Error, {
|
|
126
|
-
status:
|
|
127
|
-
data: {
|
|
128
|
-
operation: 'JSON parsing',
|
|
129
|
-
input: 'invalid json'
|
|
130
|
-
}
|
|
121
|
+
status: 500,
|
|
122
|
+
data: { context: 'Parsing configuration file' }
|
|
131
123
|
});
|
|
132
124
|
}
|
|
133
125
|
```
|
|
134
126
|
|
|
135
|
-
### Stack Trace
|
|
127
|
+
### Accessing Stack Trace as JSON
|
|
136
128
|
|
|
137
129
|
```typescript
|
|
138
130
|
import { Exception } from '@ooneex/exception';
|
|
139
131
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
// source: ' at parseData (/path/to/file.ts:42:15)'
|
|
151
|
-
// },
|
|
152
|
-
// ...
|
|
153
|
-
// ]
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### Generic Data Types
|
|
157
|
-
|
|
158
|
-
```typescript
|
|
159
|
-
import { Exception } from '@ooneex/exception';
|
|
160
|
-
|
|
161
|
-
// Define custom data interface
|
|
162
|
-
interface ValidationError {
|
|
163
|
-
field: string;
|
|
164
|
-
value: unknown;
|
|
165
|
-
rule: string;
|
|
166
|
-
message: string;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Create typed exception
|
|
170
|
-
const validationException = new Exception<ValidationError>('Validation failed', {
|
|
171
|
-
status: 400,
|
|
172
|
-
data: {
|
|
173
|
-
field: 'email',
|
|
174
|
-
value: 'not-an-email',
|
|
175
|
-
rule: 'email',
|
|
176
|
-
message: 'Must be a valid email address'
|
|
132
|
+
try {
|
|
133
|
+
throw new Exception('Test error');
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (error instanceof Exception) {
|
|
136
|
+
const stackFrames = error.stackToJson();
|
|
137
|
+
|
|
138
|
+
stackFrames?.forEach((frame, index) => {
|
|
139
|
+
console.log(`${index + 1}. ${frame.functionName || '<anonymous>'}`);
|
|
140
|
+
console.log(` at ${frame.fileName}:${frame.lineNumber}:${frame.columnNumber}`);
|
|
141
|
+
});
|
|
177
142
|
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// TypeScript ensures type safety
|
|
181
|
-
console.log(validationException.data?.field); // string
|
|
182
|
-
console.log(validationException.data?.rule); // string
|
|
143
|
+
}
|
|
183
144
|
```
|
|
184
145
|
|
|
185
146
|
## API Reference
|
|
186
147
|
|
|
187
|
-
###
|
|
148
|
+
### Classes
|
|
188
149
|
|
|
189
|
-
|
|
150
|
+
#### `Exception`
|
|
190
151
|
|
|
191
|
-
|
|
152
|
+
Base exception class that extends the native `Error` with additional metadata.
|
|
192
153
|
|
|
154
|
+
**Constructor:**
|
|
193
155
|
```typescript
|
|
194
|
-
new Exception
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
156
|
+
new Exception(
|
|
157
|
+
message: string | Error,
|
|
158
|
+
options?: {
|
|
159
|
+
status?: StatusCodeType;
|
|
160
|
+
data?: Record<string, unknown>;
|
|
161
|
+
}
|
|
162
|
+
)
|
|
198
163
|
```
|
|
199
164
|
|
|
200
165
|
**Parameters:**
|
|
201
166
|
- `message` - Error message string or native Error object to wrap
|
|
202
|
-
- `options.status` - HTTP status code (
|
|
203
|
-
- `options.data` -
|
|
204
|
-
|
|
205
|
-
#### Properties
|
|
167
|
+
- `options.status` - HTTP status code (default: 500)
|
|
168
|
+
- `options.data` - Additional contextual data
|
|
206
169
|
|
|
207
|
-
|
|
208
|
-
Timestamp when the exception was created.
|
|
170
|
+
**Properties:**
|
|
209
171
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const exception = new Exception('Not found', { status: 404 });
|
|
220
|
-
console.log(exception.status); // 404
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
##### `data?: T` (readonly)
|
|
224
|
-
Custom data object associated with the exception. Automatically frozen to prevent mutations.
|
|
172
|
+
| Property | Type | Description |
|
|
173
|
+
|----------|------|-------------|
|
|
174
|
+
| `date` | `Date` | Timestamp when the exception was created |
|
|
175
|
+
| `status` | `StatusCodeType` | HTTP status code |
|
|
176
|
+
| `data` | `Readonly<Record<string, unknown>>` | Immutable custom data |
|
|
177
|
+
| `native` | `Error \| undefined` | Original Error if wrapping a native error |
|
|
178
|
+
| `message` | `string` | Error message |
|
|
179
|
+
| `name` | `string` | Exception class name |
|
|
180
|
+
| `stack` | `string \| undefined` | Stack trace string |
|
|
225
181
|
|
|
226
|
-
|
|
227
|
-
const exception = new Exception('Error', {
|
|
228
|
-
data: { userId: 123, action: 'delete' }
|
|
229
|
-
});
|
|
230
|
-
console.log(exception.data); // { userId: 123, action: 'delete' }
|
|
231
|
-
// exception.data.userId = 456; // TypeError: Cannot assign to read only property
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
##### `native?: Error` (readonly)
|
|
235
|
-
Original native Error object when wrapping existing errors.
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
const originalError = new Error('Original message');
|
|
239
|
-
const exception = new Exception(originalError);
|
|
240
|
-
console.log(exception.native); // Original Error object
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
##### `message: string`
|
|
244
|
-
Error message (inherited from Error).
|
|
245
|
-
|
|
246
|
-
##### `name: string`
|
|
247
|
-
Exception name (inherited from Error).
|
|
248
|
-
|
|
249
|
-
##### `stack?: string`
|
|
250
|
-
Stack trace string (inherited from Error).
|
|
251
|
-
|
|
252
|
-
#### Methods
|
|
182
|
+
**Methods:**
|
|
253
183
|
|
|
254
184
|
##### `stackToJson(): ExceptionStackFrameType[] | null`
|
|
255
|
-
Parses the stack trace into a structured JSON format.
|
|
256
185
|
|
|
257
|
-
|
|
186
|
+
Converts the stack trace into a structured JSON array.
|
|
187
|
+
|
|
188
|
+
**Returns:** Array of stack frames or null if no stack trace is available
|
|
258
189
|
|
|
259
190
|
**Example:**
|
|
260
191
|
```typescript
|
|
261
|
-
const exception = new Exception('
|
|
192
|
+
const exception = new Exception('Test error');
|
|
262
193
|
const frames = exception.stackToJson();
|
|
263
194
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
195
|
+
console.log(frames);
|
|
196
|
+
// [
|
|
197
|
+
// {
|
|
198
|
+
// functionName: 'myFunction',
|
|
199
|
+
// fileName: '/path/to/file.ts',
|
|
200
|
+
// lineNumber: 42,
|
|
201
|
+
// columnNumber: 15,
|
|
202
|
+
// source: ' at myFunction (/path/to/file.ts:42:15)'
|
|
203
|
+
// },
|
|
204
|
+
// ...
|
|
205
|
+
// ]
|
|
271
206
|
```
|
|
272
207
|
|
|
273
|
-
|
|
208
|
+
#### `BadRequestException`
|
|
274
209
|
|
|
275
|
-
|
|
276
|
-
HTTP 400 Bad Request exception.
|
|
210
|
+
Exception for 400 Bad Request errors.
|
|
277
211
|
|
|
278
212
|
```typescript
|
|
279
|
-
new BadRequestException
|
|
213
|
+
new BadRequestException(message: string, options?: { data?: Record<string, unknown> })
|
|
280
214
|
```
|
|
281
215
|
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
throw new BadRequestException('Invalid request data', {
|
|
285
|
-
validationErrors: ['email is required', 'age must be a number']
|
|
286
|
-
});
|
|
287
|
-
```
|
|
216
|
+
#### `NotFoundException`
|
|
288
217
|
|
|
289
|
-
|
|
290
|
-
HTTP 401 Unauthorized exception.
|
|
218
|
+
Exception for 404 Not Found errors.
|
|
291
219
|
|
|
292
220
|
```typescript
|
|
293
|
-
new
|
|
221
|
+
new NotFoundException(message: string, options?: { data?: Record<string, unknown> })
|
|
294
222
|
```
|
|
295
223
|
|
|
296
|
-
|
|
297
|
-
```typescript
|
|
298
|
-
throw new UnauthorizedException('Access token expired', {
|
|
299
|
-
tokenType: 'Bearer',
|
|
300
|
-
expiredAt: new Date()
|
|
301
|
-
});
|
|
302
|
-
```
|
|
224
|
+
#### `UnauthorizedException`
|
|
303
225
|
|
|
304
|
-
|
|
305
|
-
HTTP 404 Not Found exception.
|
|
226
|
+
Exception for 401 Unauthorized errors.
|
|
306
227
|
|
|
307
228
|
```typescript
|
|
308
|
-
new
|
|
229
|
+
new UnauthorizedException(message: string, options?: { data?: Record<string, unknown> })
|
|
309
230
|
```
|
|
310
231
|
|
|
311
|
-
|
|
312
|
-
```typescript
|
|
313
|
-
throw new NotFoundException('User not found', {
|
|
314
|
-
userId: 123,
|
|
315
|
-
searchedBy: 'email'
|
|
316
|
-
});
|
|
317
|
-
```
|
|
232
|
+
#### `MethodNotAllowedException`
|
|
318
233
|
|
|
319
|
-
|
|
320
|
-
HTTP 405 Method Not Allowed exception.
|
|
234
|
+
Exception for 405 Method Not Allowed errors.
|
|
321
235
|
|
|
322
236
|
```typescript
|
|
323
|
-
new MethodNotAllowedException
|
|
237
|
+
new MethodNotAllowedException(message: string, options?: { data?: Record<string, unknown> })
|
|
324
238
|
```
|
|
325
239
|
|
|
326
|
-
|
|
240
|
+
### Types
|
|
241
|
+
|
|
242
|
+
#### `IException`
|
|
243
|
+
|
|
327
244
|
```typescript
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
245
|
+
interface IException {
|
|
246
|
+
readonly date: Date;
|
|
247
|
+
readonly status: StatusCodeType;
|
|
248
|
+
readonly data: Readonly<Record<string, unknown>>;
|
|
249
|
+
readonly native?: Error;
|
|
250
|
+
readonly message: string;
|
|
251
|
+
readonly name: string;
|
|
252
|
+
readonly stack?: string;
|
|
253
|
+
stackToJson: () => ExceptionStackFrameType[] | null;
|
|
254
|
+
}
|
|
332
255
|
```
|
|
333
256
|
|
|
334
|
-
### Types and Interfaces
|
|
335
|
-
|
|
336
257
|
#### `ExceptionStackFrameType`
|
|
337
|
-
Represents a single frame in a parsed stack trace.
|
|
338
258
|
|
|
339
259
|
```typescript
|
|
340
260
|
type ExceptionStackFrameType = {
|
|
@@ -346,112 +266,103 @@ type ExceptionStackFrameType = {
|
|
|
346
266
|
};
|
|
347
267
|
```
|
|
348
268
|
|
|
349
|
-
#### `IException<T>`
|
|
350
|
-
Interface defining the exception contract.
|
|
351
|
-
|
|
352
|
-
```typescript
|
|
353
|
-
interface IException<T = unknown> {
|
|
354
|
-
readonly date: Date;
|
|
355
|
-
readonly status?: StatusCodeType;
|
|
356
|
-
readonly data?: Readonly<Record<string, T>>;
|
|
357
|
-
readonly native?: Error;
|
|
358
|
-
readonly message: string;
|
|
359
|
-
readonly name: string;
|
|
360
|
-
readonly stack?: string;
|
|
361
|
-
stackToJson(): ExceptionStackFrameType[] | null;
|
|
362
|
-
}
|
|
363
|
-
```
|
|
364
|
-
|
|
365
269
|
## Advanced Usage
|
|
366
270
|
|
|
367
|
-
### Custom
|
|
271
|
+
### Creating Custom Exceptions
|
|
368
272
|
|
|
369
273
|
```typescript
|
|
370
274
|
import { Exception } from '@ooneex/exception';
|
|
371
275
|
import { HttpStatus } from '@ooneex/http-status';
|
|
372
276
|
|
|
373
|
-
class
|
|
374
|
-
constructor(
|
|
277
|
+
class ValidationException extends Exception {
|
|
278
|
+
constructor(
|
|
279
|
+
message: string,
|
|
280
|
+
public readonly errors: string[]
|
|
281
|
+
) {
|
|
375
282
|
super(message, {
|
|
376
|
-
status: HttpStatus.Code.
|
|
377
|
-
data
|
|
283
|
+
status: HttpStatus.Code.BadRequest,
|
|
284
|
+
data: { errors }
|
|
378
285
|
});
|
|
286
|
+
this.name = 'ValidationException';
|
|
379
287
|
}
|
|
380
288
|
}
|
|
381
289
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
currency: 'USD'
|
|
387
|
-
});
|
|
290
|
+
throw new ValidationException('Validation failed', [
|
|
291
|
+
'Email is required',
|
|
292
|
+
'Password must be at least 8 characters'
|
|
293
|
+
]);
|
|
388
294
|
```
|
|
389
295
|
|
|
390
|
-
### Error
|
|
296
|
+
### Error Handling in Controllers
|
|
391
297
|
|
|
392
298
|
```typescript
|
|
393
|
-
import { Exception } from '@ooneex/exception';
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
299
|
+
import { Exception, NotFoundException, BadRequestException } from '@ooneex/exception';
|
|
300
|
+
import type { IController, ContextType } from '@ooneex/controller';
|
|
301
|
+
|
|
302
|
+
class UserController implements IController {
|
|
303
|
+
public async index(context: ContextType) {
|
|
304
|
+
try {
|
|
305
|
+
const user = await this.findUser(context.params.id);
|
|
306
|
+
return context.response.json({ user });
|
|
307
|
+
} catch (error) {
|
|
308
|
+
if (error instanceof NotFoundException) {
|
|
309
|
+
return context.response.notFound(error.message, {
|
|
310
|
+
data: error.data
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (error instanceof Exception) {
|
|
315
|
+
return context.response.exception(error.message, {
|
|
316
|
+
status: error.status,
|
|
317
|
+
data: error.data
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
throw error;
|
|
322
|
+
}
|
|
401
323
|
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// Serialize for logging or API responses
|
|
405
|
-
const serialized = JSON.stringify({
|
|
406
|
-
message: exception.message,
|
|
407
|
-
name: exception.name,
|
|
408
|
-
status: exception.status,
|
|
409
|
-
data: exception.data,
|
|
410
|
-
date: exception.date,
|
|
411
|
-
stackFrames: exception.stackToJson()
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
console.log(serialized);
|
|
324
|
+
}
|
|
415
325
|
```
|
|
416
326
|
|
|
417
|
-
###
|
|
327
|
+
### Logging Exceptions
|
|
418
328
|
|
|
419
329
|
```typescript
|
|
420
|
-
import
|
|
421
|
-
import {
|
|
422
|
-
|
|
423
|
-
const app = express();
|
|
330
|
+
import { Exception } from '@ooneex/exception';
|
|
331
|
+
import { TerminalLogger } from '@ooneex/logger';
|
|
424
332
|
|
|
425
|
-
|
|
426
|
-
const userId = req.params.id;
|
|
333
|
+
const logger = new TerminalLogger();
|
|
427
334
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
335
|
+
try {
|
|
336
|
+
// Some operation that might fail
|
|
337
|
+
throw new Exception('Database connection failed', {
|
|
338
|
+
status: 500,
|
|
339
|
+
data: { host: 'localhost', port: 5432 }
|
|
340
|
+
});
|
|
341
|
+
} catch (error) {
|
|
342
|
+
if (error instanceof Exception) {
|
|
343
|
+
logger.error(error);
|
|
435
344
|
}
|
|
345
|
+
}
|
|
346
|
+
```
|
|
436
347
|
|
|
437
|
-
|
|
438
|
-
});
|
|
348
|
+
### Serializing Exceptions for API Responses
|
|
439
349
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
}
|
|
350
|
+
```typescript
|
|
351
|
+
import { Exception } from '@ooneex/exception';
|
|
352
|
+
|
|
353
|
+
function serializeException(exception: Exception) {
|
|
354
|
+
return {
|
|
355
|
+
error: {
|
|
356
|
+
message: exception.message,
|
|
357
|
+
status: exception.status,
|
|
358
|
+
timestamp: exception.date.toISOString(),
|
|
359
|
+
data: exception.data,
|
|
360
|
+
stack: process.env.NODE_ENV !== 'production'
|
|
361
|
+
? exception.stackToJson()
|
|
362
|
+
: undefined
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
}
|
|
455
366
|
```
|
|
456
367
|
|
|
457
368
|
## License
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{HttpStatus as
|
|
2
|
-
`),
|
|
1
|
+
import{HttpStatus as F}from"@ooneex/http-status";class p extends Error{date=new Date;status;data;native;constructor(t,r){super(t instanceof Error?t.message:t);if(this.status=r?.status||500,this.data=r?.data||{},t instanceof Error)this.native=t;this.name=this.constructor.name,this.data=Object.freeze(this.data)}stackToJson(){if(!this.stack)return null;let t=this.stack.split(`
|
|
2
|
+
`),r=[];for(let u=1;u<t.length;u++){let E=t[u]?.trim();if(!E)continue;let o={source:E},R=E.match(/^\s*at\s+(.+)$/);if(R){let s=R[1],y=s?.match(/^(.+?)\s+\((.+)\)$/);if(y){let e=y[1],d=y[2];if(e)o.functionName=e;let n=d?.match(/^(.+):(\d+):(\d+)$/);if(n){let x=n[1],i=n[2],w=n[3];if(x)o.fileName=x;if(i)o.lineNumber=Number.parseInt(i,10);if(w)o.columnNumber=Number.parseInt(w,10)}else if(d)o.fileName=d}else{let e=s?.match(/^(.+):(\d+):(\d+)$/);if(e){let d=e[1],n=e[2],x=e[3];if(d)o.fileName=d;if(n)o.lineNumber=Number.parseInt(n,10);if(x)o.columnNumber=Number.parseInt(x,10)}else if(s)o.functionName=s}}r.push(o)}return r}}class S extends p{constructor(t,r={}){super(t,{status:F.Code.BadRequest,data:r});this.name="BadRequestException"}}import{HttpStatus as T}from"@ooneex/http-status";class k extends p{constructor(t,r={}){super(t,{status:T.Code.MethodNotAllowed,data:r});this.name="MethodNotAllowedException"}}import{HttpStatus as q}from"@ooneex/http-status";class g extends p{constructor(t,r={}){super(t,{status:q.Code.NotFound,data:r});this.name="NotFoundException"}}import{HttpStatus as z}from"@ooneex/http-status";class C extends p{constructor(t,r={}){super(t,{status:z.Code.Unauthorized,data:r});this.name="UnauthorizedException"}}export{C as UnauthorizedException,g as NotFoundException,k as MethodNotAllowedException,p as Exception,S as BadRequestException};
|
|
3
3
|
|
|
4
|
-
//# debugId=
|
|
4
|
+
//# debugId=70B57CA4AB9AB8CA64756E2164756E21
|
package/dist/index.js.map
CHANGED
|
@@ -9,6 +9,6 @@
|
|
|
9
9
|
"import { HttpStatus } from \"@ooneex/http-status\";\nimport { Exception } from \"./Exception\";\n\nexport class UnauthorizedException extends Exception {\n constructor(message: string, data: Record<string, unknown> = {}) {\n super(message, {\n status: HttpStatus.Code.Unauthorized,\n data,\n });\n this.name = \"UnauthorizedException\";\n }\n}\n"
|
|
10
10
|
],
|
|
11
11
|
"mappings": "AAAA,qBAAS,4BCGF,MAAM,UAAkB,KAA4B,CACzC,KAAa,IAAI,KACjB,OACA,KACA,OAEhB,WAAW,CAAC,EAAyB,EAAuE,CAC1G,MAAM,aAAmB,MAAS,EAAkB,QAAU,CAAO,EAKrE,GAHA,KAAK,OAAS,GAAS,QAAU,IACjC,KAAK,KAAO,GAAS,MAAQ,CAAC,EAE1B,aAAmB,MACrB,KAAK,OAAS,EAEhB,KAAK,KAAO,KAAK,YAAY,KAC7B,KAAK,KAAO,OAAO,OAAO,KAAK,IAAI,EAO9B,WAAW,EAAqC,CACrD,GAAI,CAAC,KAAK,MACR,OAAO,KAGT,IAAM,EAAa,KAAK,MAAM,MAAM;AAAA,CAAI,EAClC,EAAoC,CAAC,EAG3C,QAAS,EAAI,EAAG,EAAI,EAAW,OAAQ,IAAK,CAC1C,IAAM,EAAO,EAAW,IAAI,KAAK,EACjC,GAAI,CAAC,EAAM,SAEX,IAAM,EAAiC,CACrC,OAAQ,CACV,EAOM,EAAU,EAAK,MAAM,gBAAgB,EAC3C,GAAI,EAAS,CACX,IAAM,EAAU,EAAQ,GAGlB,EAAwB,GAAS,MAAM,oBAAoB,EACjE,GAAI,EAAuB,CACzB,IAAM,EAAe,EAAsB,GACrC,EAAW,EAAsB,GAEvC,GAAI,EACF,EAAM,aAAe,EAIvB,IAAM,EAAgB,GAAU,MAAM,oBAAoB,EAC1D,GAAI,EAAe,CACjB,IAAM,EAAW,EAAc,GACzB,EAAU,EAAc,GACxB,EAAS,EAAc,GAE7B,GAAI,EACF,EAAM,SAAW,EAEnB,GAAI,EACF,EAAM,WAAa,OAAO,SAAS,EAAS,EAAE,EAEhD,GAAI,EACF,EAAM,aAAe,OAAO,SAAS,EAAQ,EAAE,EAE5C,QAAI,EACT,EAAM,SAAW,EAEd,KAEL,IAAM,EAAsB,GAAS,MAAM,oBAAoB,EAC/D,GAAI,EAAqB,CACvB,IAAM,EAAW,EAAoB,GAC/B,EAAU,EAAoB,GAC9B,EAAS,EAAoB,GAEnC,GAAI,EACF,EAAM,SAAW,EAEnB,GAAI,EACF,EAAM,WAAa,OAAO,SAAS,EAAS,EAAE,EAEhD,GAAI,EACF,EAAM,aAAe,OAAO,SAAS,EAAQ,EAAE,EAE5C,QAAI,EAET,EAAM,aAAe,GAK3B,EAAO,KAAK,CAAK,EAGnB,OAAO,EAEX,CD3GO,MAAM,UAA4B,CAAU,CACjD,WAAW,CAAC,EAAiB,EAAgC,CAAC,EAAG,CAC/D,MAAM,EAAS,CACb,OAAQ,EAAW,KAAK,WACxB,MACF,CAAC,EACD,KAAK,KAAO,sBAEhB,CEXA,qBAAS,4BAGF,MAAM,UAAkC,CAAU,CACvD,WAAW,CAAC,EAAiB,EAAgC,CAAC,EAAG,CAC/D,MAAM,EAAS,CACb,OAAQ,EAAW,KAAK,iBACxB,MACF,CAAC,EACD,KAAK,KAAO,4BAEhB,CCXA,qBAAS,4BAGF,MAAM,UAA0B,CAAU,CAC/C,WAAW,CAAC,EAAiB,EAAgC,CAAC,EAAG,CAC/D,MAAM,EAAS,CACb,OAAQ,EAAW,KAAK,SACxB,MACF,CAAC,EACD,KAAK,KAAO,oBAEhB,CCXA,qBAAS,4BAGF,MAAM,UAA8B,CAAU,CACnD,WAAW,CAAC,EAAiB,EAAgC,CAAC,EAAG,CAC/D,MAAM,EAAS,CACb,OAAQ,EAAW,KAAK,aACxB,MACF,CAAC,EACD,KAAK,KAAO,wBAEhB",
|
|
12
|
-
"debugId": "
|
|
12
|
+
"debugId": "70B57CA4AB9AB8CA64756E2164756E21",
|
|
13
13
|
"names": []
|
|
14
14
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ooneex/exception",
|
|
3
|
-
"description": "",
|
|
4
|
-
"version": "0.0.
|
|
3
|
+
"description": "Type-safe exception handling with HTTP status code integration for structured error management",
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -25,13 +25,18 @@
|
|
|
25
25
|
"test": "bun test tests",
|
|
26
26
|
"build": "bunup",
|
|
27
27
|
"lint": "tsgo --noEmit && bunx biome lint",
|
|
28
|
-
"publish
|
|
29
|
-
"publish:pack": "bun pm pack --destination ./dist",
|
|
30
|
-
"publish:dry": "bun publish --dry-run"
|
|
28
|
+
"npm:publish": "bun publish --tolerate-republish --access public"
|
|
31
29
|
},
|
|
32
30
|
"dependencies": {
|
|
33
31
|
"@ooneex/http-status": "0.0.1"
|
|
34
32
|
},
|
|
35
33
|
"devDependencies": {},
|
|
36
|
-
"
|
|
34
|
+
"keywords": [
|
|
35
|
+
"bun",
|
|
36
|
+
"error",
|
|
37
|
+
"error-handling",
|
|
38
|
+
"exception",
|
|
39
|
+
"ooneex",
|
|
40
|
+
"typescript"
|
|
41
|
+
]
|
|
37
42
|
}
|
|
Binary file
|