exisjs 0.7.12 → 0.7.13
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 +195 -39
- package/dist/config/types.d.ts +2 -2
- package/dist/config/types.d.ts.map +1 -1
- package/dist/decorators/params.d.ts +21 -0
- package/dist/decorators/params.d.ts.map +1 -1
- package/dist/decorators/params.js +21 -1
- package/dist/decorators/params.js.map +1 -1
- package/dist/di/container.d.ts +15 -6
- package/dist/di/container.d.ts.map +1 -1
- package/dist/di/container.js +26 -3
- package/dist/di/container.js.map +1 -1
- package/dist/di/index.d.ts +1 -1
- package/dist/di/index.d.ts.map +1 -1
- package/dist/di/index.js.map +1 -1
- package/dist/di/inject.d.ts +2 -1
- package/dist/di/inject.d.ts.map +1 -1
- package/dist/di/inject.js +2 -1
- package/dist/di/inject.js.map +1 -1
- package/dist/docs/BENCHMARKS.md +4 -4
- package/dist/docs/content/README.md +43 -44
- package/dist/docs/content/boundaries.mdx +138 -61
- package/dist/docs/content/cli/commands.mdx +151 -128
- package/dist/docs/content/cli/overview.mdx +61 -47
- package/dist/docs/content/cli/usage.mdx +107 -30
- package/dist/docs/content/config.mdx +145 -158
- package/dist/docs/content/controllers.mdx +193 -464
- package/dist/docs/content/cron.mdx +183 -69
- package/dist/docs/content/decorators.mdx +449 -154
- package/dist/docs/content/errors.mdx +202 -305
- package/dist/docs/content/exisjs-mcp.mdx +59 -49
- package/dist/docs/content/installation.mdx +243 -157
- package/dist/docs/content/introduction.mdx +220 -48
- package/dist/docs/content/middleware.mdx +171 -497
- package/dist/docs/content/modules.mdx +141 -83
- package/dist/docs/content/providers.mdx +216 -180
- package/dist/docs/content/requests.mdx +168 -488
- package/dist/docs/content/responses.mdx +200 -533
- package/dist/docs/content/routing.mdx +235 -598
- package/dist/docs/content/security.mdx +233 -57
- package/dist/docs/content/structure.mdx +151 -240
- package/dist/docs/content/swagger.mdx +192 -91
- package/dist/docs/content/testing.mdx +205 -74
- package/dist/docs/content/validation.mdx +479 -341
- package/dist/docs/reference/README.md +34 -2
- package/dist/docs/reference/config.mdx +277 -75
- package/dist/docs/reference/context.mdx +197 -106
- package/dist/docs/reference/cron.mdx +266 -152
- package/dist/docs/reference/database.mdx +135 -53
- package/dist/docs/reference/decorators.mdx +234 -116
- package/dist/docs/reference/di.mdx +146 -112
- package/dist/docs/reference/error.mdx +155 -178
- package/dist/docs/reference/exis.mdx +141 -70
- package/dist/docs/reference/logger.mdx +110 -126
- package/dist/docs/reference/middleware.mdx +235 -158
- package/dist/docs/reference/plugin.mdx +136 -64
- package/dist/docs/reference/router.mdx +275 -293
- package/dist/docs/reference/sanitize.mdx +91 -87
- package/dist/docs/reference/swagger.mdx +280 -100
- package/dist/docs/reference/testing.mdx +223 -89
- package/dist/docs/reference/validator.mdx +194 -206
- package/dist/lib/start-server.js +3 -8
- package/dist/lib/start-server.js.map +1 -1
- package/dist/module/module.d.ts +6 -3
- package/dist/module/module.d.ts.map +1 -1
- package/dist/module/module.js +17 -3
- package/dist/module/module.js.map +1 -1
- package/dist/router/controller-registrar.d.ts.map +1 -1
- package/dist/router/controller-registrar.js +26 -4
- package/dist/router/controller-registrar.js.map +1 -1
- package/dist/server/app.d.ts +3 -1
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +24 -8
- package/dist/server/app.js.map +1 -1
- package/dist/server/request.d.ts +2 -0
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/request.js +11 -0
- package/dist/server/request.js.map +1 -1
- package/dist/swagger/generator.d.ts.map +1 -1
- package/dist/swagger/generator.js +130 -10
- package/dist/swagger/generator.js.map +1 -1
- package/dist/telemetry/index.d.ts +12 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +121 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/testing/client.d.ts +1 -0
- package/dist/testing/client.d.ts.map +1 -1
- package/dist/testing/client.js +4 -1
- package/dist/testing/client.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +11 -4
- package/dist/testing/index.js.map +1 -1
- package/dist/validator/builder.d.ts +26 -1
- package/dist/validator/builder.d.ts.map +1 -1
- package/dist/validator/builder.js +31 -0
- package/dist/validator/builder.js.map +1 -1
- package/dist/validator/engine.d.ts +23 -0
- package/dist/validator/engine.d.ts.map +1 -1
- package/dist/validator/engine.js +228 -31
- package/dist/validator/engine.js.map +1 -1
- package/dist/validator/index.d.ts +8 -4
- package/dist/validator/index.d.ts.map +1 -1
- package/dist/validator/index.js +4 -1
- package/dist/validator/index.js.map +1 -1
- package/dist/validator/tex-types.d.ts +15 -0
- package/dist/validator/tex-types.d.ts.map +1 -1
- package/dist/validator/tex-types.js +102 -0
- package/dist/validator/tex-types.js.map +1 -1
- package/dist/validator/tex.d.ts +1 -1
- package/dist/validator/tex.d.ts.map +1 -1
- package/dist/validator/tex.js +3 -1
- package/dist/validator/tex.js.map +1 -1
- package/dist/validator/types.d.ts +1 -0
- package/dist/validator/types.d.ts.map +1 -1
- package/package.json +46 -14
- package/dist/docs/content/dataloader.mdx +0 -170
- package/dist/docs/reference/dataloader.mdx +0 -91
|
@@ -1,131 +1,176 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
3
|
-
description: "API Reference for ExisJS
|
|
2
|
+
title: "exisjs/error"
|
|
3
|
+
description: "API Reference for ExisJS HTTP error hierarchy, exception classes, factory methods, global error handlers, and developer overlay utilities."
|
|
4
|
+
nextUrl: "/docs/reference/middleware"
|
|
5
|
+
nextTitle: "Middleware Reference"
|
|
4
6
|
---
|
|
5
7
|
|
|
6
|
-
#
|
|
8
|
+
# `exisjs/error`
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
The `exisjs/error` module provides the standardized HTTP exception hierarchy, factory helpers, error file convention handlers, and terminal diagnostic formatters.
|
|
9
11
|
|
|
10
12
|
---
|
|
11
13
|
|
|
12
|
-
##
|
|
14
|
+
## Module Exports
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
```typescript
|
|
17
|
+
import {
|
|
18
|
+
// Base & Error Classes
|
|
19
|
+
HttpError,
|
|
20
|
+
BadRequestError,
|
|
21
|
+
UnauthorizedError,
|
|
22
|
+
ForbiddenError,
|
|
23
|
+
NotFoundError,
|
|
24
|
+
ConflictError,
|
|
25
|
+
PayloadTooLargeError,
|
|
26
|
+
UnprocessableError,
|
|
27
|
+
RateLimitError,
|
|
28
|
+
InternalError,
|
|
29
|
+
|
|
30
|
+
// Exception Aliases
|
|
31
|
+
HttpException,
|
|
32
|
+
BadRequestException,
|
|
33
|
+
UnauthorizedException,
|
|
34
|
+
ForbiddenException,
|
|
35
|
+
NotFoundException,
|
|
36
|
+
ConflictException,
|
|
37
|
+
PayloadTooLargeException,
|
|
38
|
+
UnprocessableException,
|
|
39
|
+
RateLimitException,
|
|
40
|
+
InternalException,
|
|
41
|
+
|
|
42
|
+
// Handlers & Pipeline
|
|
43
|
+
createErrorHandler,
|
|
44
|
+
asyncHandler,
|
|
45
|
+
|
|
46
|
+
// Error Diagnostic & Formatting Utilities
|
|
47
|
+
stripInternalStackFrames,
|
|
48
|
+
categorizeError,
|
|
49
|
+
generateErrorHint,
|
|
50
|
+
parseErrorLocation,
|
|
51
|
+
buildCodeFrame,
|
|
52
|
+
renderDevErrorToString,
|
|
53
|
+
formatDevError,
|
|
54
|
+
formatCliError,
|
|
55
|
+
devErrorResponse,
|
|
56
|
+
} from 'exisjs/error'
|
|
15
57
|
|
|
16
|
-
|
|
58
|
+
import type { ParsedError } from 'exisjs/error'
|
|
59
|
+
```
|
|
17
60
|
|
|
18
|
-
|
|
61
|
+
---
|
|
19
62
|
|
|
20
|
-
|
|
21
|
-
```typescript filename="src/http/users/route.ts"
|
|
22
|
-
import { Controller, Get, Param } from 'exisjs/decorators'
|
|
23
|
-
import { HttpError } from 'exisjs/error'
|
|
63
|
+
## 1. `HttpError` Base Class
|
|
24
64
|
|
|
25
|
-
|
|
26
|
-
export default class UserController {
|
|
27
|
-
@Get('/:id')
|
|
28
|
-
async getUser(@Param('id') id: string) {
|
|
29
|
-
const user = await db.users.find(id)
|
|
30
|
-
|
|
31
|
-
if (!user) throw HttpError.notFound('User could not be found')
|
|
32
|
-
if (user.isBanned) throw HttpError.forbidden('User account is suspended')
|
|
65
|
+
All framework exceptions inherit from `HttpError`.
|
|
33
66
|
|
|
34
|
-
|
|
35
|
-
|
|
67
|
+
```typescript
|
|
68
|
+
export class HttpError extends Error {
|
|
69
|
+
public readonly statusCode: number
|
|
70
|
+
public readonly code: string
|
|
71
|
+
public readonly isOperational: boolean
|
|
72
|
+
public readonly details?: unknown
|
|
73
|
+
|
|
74
|
+
constructor(
|
|
75
|
+
message: string,
|
|
76
|
+
statusCode = 500,
|
|
77
|
+
code = 'INTERNAL_ERROR',
|
|
78
|
+
details?: unknown
|
|
79
|
+
)
|
|
36
80
|
}
|
|
37
81
|
```
|
|
38
82
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
83
|
+
### Static Factory Methods
|
|
84
|
+
|
|
85
|
+
| Factory Method | Status Code | Default Code | Default Message |
|
|
86
|
+
| :--- | :--- | :--- | :--- |
|
|
87
|
+
| `HttpError.badRequest(msg, details?)` | `400` | `'BAD_REQUEST'` | Required |
|
|
88
|
+
| `HttpError.unauthorized(msg?)` | `401` | `'UNAUTHORIZED'` | `'Unauthorized'` |
|
|
89
|
+
| `HttpError.forbidden(msg?)` | `403` | `'FORBIDDEN'` | `'Forbidden'` |
|
|
90
|
+
| `HttpError.notFound(resource?)` | `404` | `'NOT_FOUND'` | `'Resource not found'` |
|
|
91
|
+
| `HttpError.conflict(msg)` | `409` | `'CONFLICT'` | Required |
|
|
92
|
+
| `HttpError.payloadTooLarge(msg?, details?)` | `413` | `'PAYLOAD_TOO_LARGE'` | `'Payload too large'` |
|
|
93
|
+
| `HttpError.unprocessable(msg, details?)` | `422` | `'UNPROCESSABLE_ENTITY'` | Required |
|
|
94
|
+
| `HttpError.tooManyRequests(msg?)` | `429` | `'TOO_MANY_REQUESTS'` | `'Too many requests'` |
|
|
95
|
+
| `HttpError.internal(msg?)` | `500` | `'INTERNAL_ERROR'` | `'Internal server error'` |
|
|
96
|
+
| `HttpError.serviceUnavailable(msg?)` | `503` | `'SERVICE_UNAVAILABLE'` | `'Service unavailable'` |
|
|
43
97
|
|
|
44
|
-
|
|
45
|
-
getUser: route.get('/:id', {
|
|
46
|
-
async handle(ctx) {
|
|
47
|
-
const user = await db.users.find(ctx.params.id)
|
|
48
|
-
|
|
49
|
-
if (!user) throw HttpError.notFound('User could not be found')
|
|
50
|
-
if (user.isBanned) throw HttpError.forbidden('User account is suspended')
|
|
98
|
+
---
|
|
51
99
|
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
```
|
|
100
|
+
## 2. Exception Classes Catalog
|
|
57
101
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
If you catch an `HttpError` or intercept it, you have access to the following properties:
|
|
73
|
-
- **`statusCode`** `(number)`: The HTTP status code.
|
|
74
|
-
- **`code`** `(string)`: The unique uppercase error code (e.g., `'NOT_FOUND'`).
|
|
75
|
-
- **`message`** `(string)`: The human-readable message.
|
|
76
|
-
- **`details`** `(unknown)`: Optional metadata attached to the error.
|
|
77
|
-
- **`isOperational`** `(boolean)`: Always `true` for `HttpError`s. Used by the global error handler to determine if an error was intentionally thrown vs an unexpected crash.
|
|
78
|
-
- **`toJSON()`**: Serializes the error into the strictly typed ExisJS `{ success: false, error: ... }` response shape.
|
|
102
|
+
Each exception class can be instantiated directly with `new` and has an equivalent `*Exception` alias:
|
|
103
|
+
|
|
104
|
+
| Error Class | Alias | Status Code | Default Code |
|
|
105
|
+
| :--- | :--- | :--- | :--- |
|
|
106
|
+
| `BadRequestError` | `BadRequestException` | `400` | `'BAD_REQUEST'` |
|
|
107
|
+
| `UnauthorizedError` | `UnauthorizedException` | `401` | `'UNAUTHORIZED'` |
|
|
108
|
+
| `ForbiddenError` | `ForbiddenException` | `403` | `'FORBIDDEN'` |
|
|
109
|
+
| `NotFoundError` | `NotFoundException` | `404` | `'NOT_FOUND'` |
|
|
110
|
+
| `ConflictError` | `ConflictException` | `409` | `'CONFLICT'` |
|
|
111
|
+
| `PayloadTooLargeError` | `PayloadTooLargeException` | `413` | `'PAYLOAD_TOO_LARGE'` |
|
|
112
|
+
| `UnprocessableError` | `UnprocessableException` | `422` | `'UNPROCESSABLE_ENTITY'` |
|
|
113
|
+
| `RateLimitError` | `RateLimitException` | `429` | `'TOO_MANY_REQUESTS'` |
|
|
114
|
+
| `InternalError` | `InternalException` | `500` | `'INTERNAL_ERROR'` |
|
|
79
115
|
|
|
80
116
|
---
|
|
81
117
|
|
|
82
|
-
##
|
|
118
|
+
## 3. Usage Examples
|
|
119
|
+
|
|
120
|
+
### Functional Route Example
|
|
83
121
|
|
|
84
|
-
|
|
122
|
+
```typescript filename="src/http/users/route.ts"
|
|
123
|
+
import { controller, route } from 'exisjs/router'
|
|
124
|
+
import { HttpError, NotFoundException } from 'exisjs/error'
|
|
85
125
|
|
|
86
|
-
|
|
87
|
-
|
|
126
|
+
export default controller({
|
|
127
|
+
getById: route.get('/:id', {
|
|
128
|
+
async handle({ params }) {
|
|
129
|
+
const user = await findUser(params.id)
|
|
130
|
+
if (!user) {
|
|
131
|
+
throw new NotFoundException(`User with ID ${params.id} not found`)
|
|
132
|
+
}
|
|
133
|
+
return user
|
|
134
|
+
},
|
|
135
|
+
}),
|
|
136
|
+
})
|
|
137
|
+
```
|
|
88
138
|
|
|
89
|
-
|
|
90
|
-
if (!isValid(token)) {
|
|
91
|
-
throw new UnauthorizedError('Invalid or expired token')
|
|
92
|
-
}
|
|
93
|
-
}
|
|
139
|
+
### Class-Based Controller Example
|
|
94
140
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
141
|
+
```typescript filename="src/http/users/route.ts"
|
|
142
|
+
import { Controller, Get, Param } from 'exisjs/decorators'
|
|
143
|
+
import { HttpError } from 'exisjs/error'
|
|
144
|
+
|
|
145
|
+
@Controller('/users')
|
|
146
|
+
export default class UserController {
|
|
147
|
+
@Get('/:id')
|
|
148
|
+
async getById(@Param('id') id: string) {
|
|
149
|
+
const user = await findUser(id)
|
|
150
|
+
if (!user) {
|
|
151
|
+
throw HttpError.notFound('User')
|
|
152
|
+
}
|
|
153
|
+
return user
|
|
98
154
|
}
|
|
99
155
|
}
|
|
100
156
|
```
|
|
101
157
|
|
|
102
|
-
### Supported Classes
|
|
103
|
-
- `BadRequestError` / `BadRequestException`
|
|
104
|
-
- `UnauthorizedError` / `UnauthorizedException`
|
|
105
|
-
- `ForbiddenError` / `ForbiddenException`
|
|
106
|
-
- `NotFoundError` / `NotFoundException`
|
|
107
|
-
- `ConflictError` / `ConflictException`
|
|
108
|
-
- `PayloadTooLargeError` / `PayloadTooLargeException`
|
|
109
|
-
- `UnprocessableError` / `UnprocessableException`
|
|
110
|
-
- `RateLimitError` / `RateLimitException`
|
|
111
|
-
- `InternalError` / `InternalException`
|
|
112
|
-
|
|
113
158
|
---
|
|
114
159
|
|
|
115
|
-
## Custom
|
|
160
|
+
## 4. Custom Application Exceptions
|
|
116
161
|
|
|
117
|
-
|
|
162
|
+
Custom domain exceptions can be constructed by extending `HttpError`:
|
|
118
163
|
|
|
119
164
|
```typescript filename="src/errors/payment.ts"
|
|
120
165
|
import { HttpError } from 'exisjs/error'
|
|
121
166
|
|
|
122
|
-
export class
|
|
123
|
-
constructor(
|
|
167
|
+
export class InsufficientBalanceError extends HttpError {
|
|
168
|
+
constructor(required: number, current: number) {
|
|
124
169
|
super(
|
|
125
|
-
'Insufficient
|
|
126
|
-
402,
|
|
127
|
-
'
|
|
128
|
-
{
|
|
170
|
+
'Insufficient balance to complete transaction',
|
|
171
|
+
402,
|
|
172
|
+
'INSUFFICIENT_BALANCE',
|
|
173
|
+
{ required, current }
|
|
129
174
|
)
|
|
130
175
|
}
|
|
131
176
|
}
|
|
@@ -133,13 +178,12 @@ export class InsufficientFundsError extends HttpError {
|
|
|
133
178
|
|
|
134
179
|
---
|
|
135
180
|
|
|
136
|
-
##
|
|
181
|
+
## 5. Global Error Handling Convention (`src/http/error.ts`)
|
|
137
182
|
|
|
138
|
-
ExisJS
|
|
183
|
+
ExisJS auto-discovers and mounts `src/http/error.ts` to centralize application error interceptors:
|
|
139
184
|
|
|
140
|
-
###
|
|
185
|
+
### Functional Style
|
|
141
186
|
|
|
142
|
-
**Functional (`export function onError`):**
|
|
143
187
|
```typescript filename="src/http/error.ts"
|
|
144
188
|
import type { Request, Response } from 'exisjs'
|
|
145
189
|
|
|
@@ -148,15 +192,16 @@ export function onError(err: any, req: Request, res: Response): void | Promise<v
|
|
|
148
192
|
res.status(status).json({
|
|
149
193
|
success: false,
|
|
150
194
|
error: {
|
|
151
|
-
code: err.code || '
|
|
152
|
-
message: err.message || '
|
|
195
|
+
code: err.code || 'INTERNAL_ERROR',
|
|
196
|
+
message: err.message || 'An unexpected error occurred',
|
|
153
197
|
path: req.path,
|
|
154
198
|
},
|
|
155
199
|
})
|
|
156
200
|
}
|
|
157
201
|
```
|
|
158
202
|
|
|
159
|
-
|
|
203
|
+
### Class-Based Style
|
|
204
|
+
|
|
160
205
|
```typescript filename="src/http/error.ts"
|
|
161
206
|
import type { Request, Response } from 'exisjs'
|
|
162
207
|
|
|
@@ -166,9 +211,8 @@ export default class GlobalErrorHandler {
|
|
|
166
211
|
res.status(status).json({
|
|
167
212
|
success: false,
|
|
168
213
|
error: {
|
|
169
|
-
code: err.code || '
|
|
170
|
-
message: err.message || '
|
|
171
|
-
path: req.path,
|
|
214
|
+
code: err.code || 'INTERNAL_ERROR',
|
|
215
|
+
message: err.message || 'An unexpected error occurred',
|
|
172
216
|
},
|
|
173
217
|
})
|
|
174
218
|
}
|
|
@@ -177,84 +221,17 @@ export default class GlobalErrorHandler {
|
|
|
177
221
|
|
|
178
222
|
---
|
|
179
223
|
|
|
180
|
-
##
|
|
181
|
-
|
|
182
|
-
ExisJS uses a highly sophisticated global error handler out of the box, generated via `createErrorHandler(isDev)`.
|
|
183
|
-
|
|
184
|
-
### Automatic Features:
|
|
185
|
-
1. **JSON Standardization**: Automatically formats all errors into a strict `{ success: false, error: { code, message, details? } }` shape.
|
|
186
|
-
2. **Third-Party Integrations**: Natively catches and normalizes schema validation errors from **Zod**, **Yup**, and the **ExisJS built-in validator**.
|
|
187
|
-
3. **Syntax Guard**: Catches malformed JSON payloads (SyntaxErrors) in the request body gracefully.
|
|
188
|
-
4. **Dev vs Prod Modes**: If `isDev` is true, unexpected internal errors (500) will attach stack traces to the response. In production, stack traces are completely stripped to prevent security leaks.
|
|
189
|
-
5. **HTML Error Pages**: In Dev mode, if a request accepts `text/html`, the error handler renders a beautiful, stylized HTML error page displaying the stack trace directly in the browser.
|
|
190
|
-
|
|
191
|
-
### Overriding the Global Handler
|
|
192
|
-
|
|
193
|
-
If you need to intercept errors before they reach the client (e.g., to send them to Sentry or Datadog), you can provide a custom global error handler:
|
|
194
|
-
|
|
195
|
-
```typescript filename="src/server.ts"
|
|
196
|
-
import { exis } from 'exisjs'
|
|
197
|
-
import { HttpError } from 'exisjs/error'
|
|
198
|
-
|
|
199
|
-
const app = exis()
|
|
200
|
-
|
|
201
|
-
app.use((err, req, res, next) => {
|
|
202
|
-
// Log unexpected errors to Sentry
|
|
203
|
-
if (!(err instanceof HttpError) || err.statusCode >= 500) {
|
|
204
|
-
Sentry.captureException(err)
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Pass it down to the default ExisJS error handler
|
|
208
|
-
next(err)
|
|
209
|
-
})
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### Express Compatibility (`asyncHandler`)
|
|
224
|
+
## 6. Developer Overlay & Formatting Utilities
|
|
213
225
|
|
|
214
|
-
|
|
226
|
+
The module exports diagnostic utilities used for CLI logging, test assertions, and debugging:
|
|
215
227
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
## Developer Error Formatting & Overlay Utilities
|
|
221
|
-
|
|
222
|
-
`exisjs/error` also exports powerful error diagnostic utilities that you can use in custom error handlers, CLI scripts, background workers, and testing:
|
|
223
|
-
|
|
224
|
-
```typescript
|
|
225
|
-
import {
|
|
226
|
-
formatDevError,
|
|
227
|
-
renderDevErrorToString,
|
|
228
|
-
categorizeError,
|
|
229
|
-
generateErrorHint,
|
|
230
|
-
buildCodeFrame,
|
|
231
|
-
stripInternalStackFrames,
|
|
232
|
-
devErrorResponse,
|
|
233
|
-
type ParsedError,
|
|
234
|
-
} from 'exisjs/error'
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### Utility Functions
|
|
238
|
-
|
|
239
|
-
| Function | Signature | Description |
|
|
228
|
+
| Utility Function | Signature | Description |
|
|
240
229
|
| :--- | :--- | :--- |
|
|
241
|
-
| `formatDevError` | `(err: Error,
|
|
242
|
-
| `renderDevErrorToString` | `(err: Error,
|
|
243
|
-
| `categorizeError` | `(err: Error) => string` |
|
|
244
|
-
| `generateErrorHint` | `(err: Error) => string \| null` |
|
|
245
|
-
| `buildCodeFrame` | `(filePath: string, line: number, col?: number) => string` |
|
|
246
|
-
| `stripInternalStackFrames` | `(stack?: string) => string[]` |
|
|
247
|
-
| `devErrorResponse` | `(err: Error, routeFile?: string) =>
|
|
248
|
-
|
|
249
|
-
### Example: Custom Worker or Script Error Handling
|
|
250
|
-
|
|
251
|
-
```typescript filename="src/workers/import-csv.ts"
|
|
252
|
-
import { formatDevError, categorizeError } from 'exisjs/error'
|
|
253
|
-
|
|
254
|
-
try {
|
|
255
|
-
await processCsvImport(filePath)
|
|
256
|
-
} catch (err: any) {
|
|
257
|
-
// Prints a clean code frame with line numbers and actionable hints directly in terminal
|
|
258
|
-
formatDevError(err, { routeFile: filePath, title: categorizeError(err) })
|
|
259
|
-
}
|
|
260
|
-
```
|
|
230
|
+
| `formatDevError` | `(err: Error, options?: { routeFile?: string; title?: string }) => void` | Prints terminal error frame with code snippet and line pointers. |
|
|
231
|
+
| `renderDevErrorToString` | `(err: Error, options?: { routeFile?: string; title?: string }) => string` | Returns the formatted terminal error box as an ANSI string. |
|
|
232
|
+
| `categorizeError` | `(err: Error) => string` | Returns a human-readable category (e.g. `'Validation Error'`). |
|
|
233
|
+
| `generateErrorHint` | `(err: Error) => string \| null` | Produces actionable remediation advice for recognized errors. |
|
|
234
|
+
| `buildCodeFrame` | `(filePath: string, line: number, col?: number) => string` | Constructs visual code snippet frame around line and column coordinates. |
|
|
235
|
+
| `stripInternalStackFrames` | `(stack?: string) => string[]` | Filters out Node.js internal and framework runtime stack frames. |
|
|
236
|
+
| `devErrorResponse` | `(err: Error, routeFile?: string) => Record<string, any>` | Formats structured JSON error response for development clients. |
|
|
237
|
+
|