@naman_deep_singh/errors-utils 1.0.0 → 1.1.1
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 +125 -0
- package/dist/{error → cjs/error}/AppError.d.ts +2 -2
- package/dist/cjs/error/BadRequestError.d.ts +4 -0
- package/dist/{error → cjs/error}/BadRequestError.js +1 -1
- package/dist/cjs/error/ConflictError.d.ts +4 -0
- package/dist/{error → cjs/error}/ConflictError.js +1 -1
- package/dist/cjs/error/ForbiddenError.d.ts +4 -0
- package/dist/{error → cjs/error}/ForbiddenError.js +1 -1
- package/dist/cjs/error/HTTPError.d.ts +5 -0
- package/dist/{error → cjs/error}/HTTPError.js +1 -1
- package/dist/cjs/error/InternalServerError.d.ts +4 -0
- package/dist/{error → cjs/error}/InternalServerError.js +1 -1
- package/dist/cjs/error/NotFoundError.d.ts +4 -0
- package/dist/{error → cjs/error}/NotFoundError.js +1 -1
- package/dist/cjs/error/UnauthorizedError.d.ts +4 -0
- package/dist/{error → cjs/error}/UnauthorizedError.js +1 -1
- package/dist/cjs/error/ValidationError.d.ts +4 -0
- package/dist/{error → cjs/error}/ValidationError.js +1 -1
- package/dist/cjs/index.d.ts +10 -0
- package/dist/{index.js → cjs/index.js} +1 -2
- package/dist/cjs/middleware/express/errorConverter.d.ts +2 -0
- package/dist/cjs/middleware/express/errorConverter.js +27 -0
- package/dist/cjs/middleware/express/errorHandler.d.ts +2 -0
- package/dist/{middleware → cjs/middleware/express}/errorHandler.js +7 -7
- package/dist/cjs/middleware/express/index.d.ts +2 -0
- package/dist/cjs/middleware/express/index.js +18 -0
- package/dist/cjs/utils/mapAppErrorToResponder.d.ts +3 -0
- package/dist/{utils → cjs/utils}/mapAppErrorToResponder.js +3 -1
- package/dist/esm/error/AppError.d.ts +6 -0
- package/{src/error/AppError.ts → dist/esm/error/AppError.js} +1 -8
- package/dist/esm/error/BadRequestError.d.ts +4 -0
- package/dist/esm/error/BadRequestError.js +6 -0
- package/dist/esm/error/ConflictError.d.ts +4 -0
- package/dist/esm/error/ConflictError.js +6 -0
- package/dist/esm/error/ForbiddenError.d.ts +4 -0
- package/dist/esm/error/ForbiddenError.js +6 -0
- package/dist/esm/error/HTTPError.d.ts +5 -0
- package/dist/esm/error/HTTPError.js +7 -0
- package/dist/esm/error/InternalServerError.d.ts +4 -0
- package/dist/esm/error/InternalServerError.js +6 -0
- package/dist/esm/error/NotFoundError.d.ts +4 -0
- package/dist/esm/error/NotFoundError.js +6 -0
- package/dist/esm/error/UnauthorizedError.d.ts +4 -0
- package/dist/esm/error/UnauthorizedError.js +6 -0
- package/dist/esm/error/ValidationError.d.ts +4 -0
- package/dist/esm/error/ValidationError.js +6 -0
- package/dist/esm/index.d.ts +10 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/middleware/express/errorConverter.d.ts +2 -0
- package/dist/esm/middleware/express/errorConverter.js +24 -0
- package/dist/esm/middleware/express/errorHandler.d.ts +2 -0
- package/dist/esm/middleware/express/errorHandler.js +15 -0
- package/dist/esm/middleware/express/index.d.ts +2 -0
- package/dist/esm/middleware/express/index.js +2 -0
- package/dist/esm/utils/mapAppErrorToResponder.d.ts +3 -0
- package/{src/utils/mapAppErrorToResponder.ts → dist/esm/utils/mapAppErrorToResponder.js} +5 -12
- package/dist/types/error/AppError.d.ts +6 -0
- package/dist/types/error/BadRequestError.d.ts +4 -0
- package/dist/types/error/ConflictError.d.ts +4 -0
- package/dist/types/error/ForbiddenError.d.ts +4 -0
- package/dist/types/error/HTTPError.d.ts +5 -0
- package/dist/types/error/InternalServerError.d.ts +4 -0
- package/dist/types/error/NotFoundError.d.ts +4 -0
- package/dist/types/error/UnauthorizedError.d.ts +4 -0
- package/dist/types/error/ValidationError.d.ts +4 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/middleware/express/errorConverter.d.ts +2 -0
- package/dist/types/middleware/express/errorHandler.d.ts +2 -0
- package/dist/types/middleware/express/index.d.ts +2 -0
- package/dist/types/utils/mapAppErrorToResponder.d.ts +3 -0
- package/package.json +23 -7
- package/dist/error/BadRequestError.d.ts +0 -4
- package/dist/error/ConflictError.d.ts +0 -4
- package/dist/error/ForbiddenError.d.ts +0 -4
- package/dist/error/HTTPError.d.ts +0 -5
- package/dist/error/InternalServerError.d.ts +0 -4
- package/dist/error/NotFoundError.d.ts +0 -4
- package/dist/error/UnauthorizedError.d.ts +0 -4
- package/dist/error/ValidationError.d.ts +0 -4
- package/dist/index.d.ts +0 -11
- package/dist/middleware/errorConverter.d.ts +0 -2
- package/dist/middleware/errorConverter.js +0 -11
- package/dist/middleware/errorHandler.d.ts +0 -2
- package/dist/utils/mapAppErrorToResponder.d.ts +0 -3
- package/src/error/BadRequestError.ts +0 -7
- package/src/error/ConflictError.ts +0 -7
- package/src/error/ForbiddenError.ts +0 -7
- package/src/error/HTTPError.ts +0 -11
- package/src/error/InternalServerError.ts +0 -7
- package/src/error/NotFoundError.ts +0 -7
- package/src/error/UnauthorizedError.ts +0 -7
- package/src/error/ValidationError.ts +0 -7
- package/src/index.ts +0 -12
- package/src/middleware/errorConverter.ts +0 -16
- package/src/middleware/errorHandler.ts +0 -25
- package/tsconfig.json +0 -21
- /package/dist/{error → cjs/error}/AppError.js +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# @naman_deep_singh/errors-utils
|
|
2
|
+
|
|
3
|
+
**Version:** 1.1.1
|
|
4
|
+
|
|
5
|
+
Standardized error classes and Express middleware for consistent error handling with TypeScript.
|
|
6
|
+
|
|
7
|
+
## 🚀 Features
|
|
8
|
+
|
|
9
|
+
- ✅ **Structured Error Classes** - AppError, HTTPError, ValidationError, etc.
|
|
10
|
+
- ✅ **Express Middleware** - Error converter and handler
|
|
11
|
+
- ✅ **Response Integration** - Works with @naman_deep_singh/response-utils
|
|
12
|
+
- ✅ **TypeScript Support** - Full type safety
|
|
13
|
+
- ✅ **Consistent Responses** - Standardized error format across your API
|
|
14
|
+
|
|
15
|
+
## 📦 Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @naman_deep_singh/errors-utils
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 🔧 Usage
|
|
22
|
+
|
|
23
|
+
### Error Classes
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import {
|
|
27
|
+
AppError,
|
|
28
|
+
BadRequestError,
|
|
29
|
+
UnauthorizedError,
|
|
30
|
+
NotFoundError,
|
|
31
|
+
ValidationError,
|
|
32
|
+
InternalServerError
|
|
33
|
+
} from '@naman_deep_singh/errors-utils';
|
|
34
|
+
|
|
35
|
+
// Basic usage
|
|
36
|
+
throw new BadRequestError('Invalid input data');
|
|
37
|
+
throw new UnauthorizedError('Authentication required');
|
|
38
|
+
throw new NotFoundError('User not found');
|
|
39
|
+
throw new ValidationError('Email is required');
|
|
40
|
+
|
|
41
|
+
// With details
|
|
42
|
+
throw new BadRequestError('Validation failed', {
|
|
43
|
+
fields: ['email', 'password']
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Express Middleware
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import express from 'express';
|
|
51
|
+
import { expressErrorHandler, errorConverter } from '@naman_deep_singh/errors-utils';
|
|
52
|
+
|
|
53
|
+
const app = express();
|
|
54
|
+
|
|
55
|
+
// Convert unknown errors to AppError
|
|
56
|
+
app.use(errorConverter);
|
|
57
|
+
|
|
58
|
+
// Handle all errors consistently
|
|
59
|
+
app.use(expressErrorHandler);
|
|
60
|
+
|
|
61
|
+
// In your routes
|
|
62
|
+
app.post('/users', (req, res) => {
|
|
63
|
+
if (!req.body.email) {
|
|
64
|
+
throw new BadRequestError('Email is required');
|
|
65
|
+
}
|
|
66
|
+
// Error will be caught and formatted automatically
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 🔗 Integration
|
|
71
|
+
|
|
72
|
+
### With @naman_deep_singh/server-utils
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { createServer } from '@naman_deep_singh/server-utils';
|
|
76
|
+
import { expressErrorHandler } from '@naman_deep_singh/errors-utils';
|
|
77
|
+
|
|
78
|
+
const server = createServer('My API', '1.0.0');
|
|
79
|
+
|
|
80
|
+
// Replace basic error handler with advanced one
|
|
81
|
+
server.app.use(expressErrorHandler);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### With @naman_deep_singh/response-utils
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { responderMiddleware } from '@naman_deep_singh/response-utils';
|
|
88
|
+
|
|
89
|
+
server.app.use(responderMiddleware());
|
|
90
|
+
server.app.use(expressErrorHandler); // Uses response-utils for consistent format
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 📚 Error Classes
|
|
94
|
+
|
|
95
|
+
| Class | Status Code | Use Case |
|
|
96
|
+
|-------|-------------|----------|
|
|
97
|
+
| `AppError` | Custom | Base error class |
|
|
98
|
+
| `BadRequestError` | 400 | Invalid input data |
|
|
99
|
+
| `UnauthorizedError` | 401 | Authentication failures |
|
|
100
|
+
| `ForbiddenError` | 403 | Authorization failures |
|
|
101
|
+
| `NotFoundError` | 404 | Resource not found |
|
|
102
|
+
| `ConflictError` | 409 | Resource conflicts |
|
|
103
|
+
| `ValidationError` | 422 | Input validation errors |
|
|
104
|
+
| `InternalServerError` | 500 | Server errors |
|
|
105
|
+
|
|
106
|
+
## 🎯 Response Format
|
|
107
|
+
|
|
108
|
+
All errors produce consistent responses:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"success": false,
|
|
113
|
+
"message": "Error message",
|
|
114
|
+
"data": undefined,
|
|
115
|
+
"error": {
|
|
116
|
+
"message": "Detailed error message",
|
|
117
|
+
"details": {...}
|
|
118
|
+
},
|
|
119
|
+
"meta": null
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## 📄 License
|
|
124
|
+
|
|
125
|
+
ISC © Naman Deep Singh
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare class AppError extends Error {
|
|
2
2
|
statusCode: number;
|
|
3
3
|
isOperational: boolean;
|
|
4
|
-
details?:
|
|
5
|
-
constructor(message: string, statusCode?: number, details?:
|
|
4
|
+
details?: unknown;
|
|
5
|
+
constructor(message: string, statusCode?: number, details?: unknown);
|
|
6
6
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BadRequestError = void 0;
|
|
4
4
|
const HTTPError_1 = require("./HTTPError");
|
|
5
5
|
class BadRequestError extends HTTPError_1.HTTPError {
|
|
6
|
-
constructor(message =
|
|
6
|
+
constructor(message = 'Bad Request', details) {
|
|
7
7
|
super(message, 400, details);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ConflictError = void 0;
|
|
4
4
|
const HTTPError_1 = require("./HTTPError");
|
|
5
5
|
class ConflictError extends HTTPError_1.HTTPError {
|
|
6
|
-
constructor(message =
|
|
6
|
+
constructor(message = 'Conflict', details) {
|
|
7
7
|
super(message, 409, details);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ForbiddenError = void 0;
|
|
4
4
|
const HTTPError_1 = require("./HTTPError");
|
|
5
5
|
class ForbiddenError extends HTTPError_1.HTTPError {
|
|
6
|
-
constructor(message =
|
|
6
|
+
constructor(message = 'Forbidden', details) {
|
|
7
7
|
super(message, 403, details);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -5,7 +5,7 @@ const AppError_1 = require("./AppError");
|
|
|
5
5
|
class HTTPError extends AppError_1.AppError {
|
|
6
6
|
constructor(message, statusCode, details) {
|
|
7
7
|
super(message, statusCode, details);
|
|
8
|
-
this.status = `${statusCode}`.startsWith(
|
|
8
|
+
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
exports.HTTPError = HTTPError;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.InternalServerError = void 0;
|
|
4
4
|
const HTTPError_1 = require("./HTTPError");
|
|
5
5
|
class InternalServerError extends HTTPError_1.HTTPError {
|
|
6
|
-
constructor(message =
|
|
6
|
+
constructor(message = 'Internal Server Error', details) {
|
|
7
7
|
super(message, 500, details);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.NotFoundError = void 0;
|
|
4
4
|
const HTTPError_1 = require("./HTTPError");
|
|
5
5
|
class NotFoundError extends HTTPError_1.HTTPError {
|
|
6
|
-
constructor(message =
|
|
6
|
+
constructor(message = 'Not Found', details) {
|
|
7
7
|
super(message, 404, details);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.UnauthorizedError = void 0;
|
|
4
4
|
const HTTPError_1 = require("./HTTPError");
|
|
5
5
|
class UnauthorizedError extends HTTPError_1.HTTPError {
|
|
6
|
-
constructor(message =
|
|
6
|
+
constructor(message = 'Unauthorized', details) {
|
|
7
7
|
super(message, 401, details);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ValidationError = void 0;
|
|
4
4
|
const HTTPError_1 = require("./HTTPError");
|
|
5
5
|
class ValidationError extends HTTPError_1.HTTPError {
|
|
6
|
-
constructor(message =
|
|
6
|
+
constructor(message = 'Validation Error', details) {
|
|
7
7
|
super(message, 422, details);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './error/AppError';
|
|
2
|
+
export * from './error/HTTPError';
|
|
3
|
+
export * from './error/BadRequestError';
|
|
4
|
+
export * from './error/UnauthorizedError';
|
|
5
|
+
export * from './error/ForbiddenError';
|
|
6
|
+
export * from './error/NotFoundError';
|
|
7
|
+
export * from './error/ConflictError';
|
|
8
|
+
export * from './error/ValidationError';
|
|
9
|
+
export * from './error/InternalServerError';
|
|
10
|
+
export * from './middleware/express';
|
|
@@ -23,5 +23,4 @@ __exportStar(require("./error/NotFoundError"), exports);
|
|
|
23
23
|
__exportStar(require("./error/ConflictError"), exports);
|
|
24
24
|
__exportStar(require("./error/ValidationError"), exports);
|
|
25
25
|
__exportStar(require("./error/InternalServerError"), exports);
|
|
26
|
-
__exportStar(require("./middleware/
|
|
27
|
-
__exportStar(require("./middleware/errorHandler"), exports);
|
|
26
|
+
__exportStar(require("./middleware/express"), exports);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.errorConverter = errorConverter;
|
|
4
|
+
const AppError_1 = require("../../error/AppError");
|
|
5
|
+
function errorConverter(err, req, res, next) {
|
|
6
|
+
if (err instanceof AppError_1.AppError) {
|
|
7
|
+
return next(err);
|
|
8
|
+
}
|
|
9
|
+
// Safely extract properties from unknown error
|
|
10
|
+
let message = 'Internal Error';
|
|
11
|
+
let statusCode = 500;
|
|
12
|
+
let details = undefined;
|
|
13
|
+
if (typeof err === 'object' && err !== null) {
|
|
14
|
+
const e = err;
|
|
15
|
+
if (typeof e.message === 'string')
|
|
16
|
+
message = e.message;
|
|
17
|
+
if (typeof e.statusCode === 'number')
|
|
18
|
+
statusCode = e.statusCode;
|
|
19
|
+
if ('details' in e)
|
|
20
|
+
details = e.details;
|
|
21
|
+
}
|
|
22
|
+
else if (typeof err === 'string') {
|
|
23
|
+
message = err;
|
|
24
|
+
}
|
|
25
|
+
const convertedError = new AppError_1.AppError(message, statusCode, details);
|
|
26
|
+
next(convertedError);
|
|
27
|
+
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const AppError_1 = require("../error/AppError");
|
|
3
|
+
exports.expressErrorHandler = expressErrorHandler;
|
|
5
4
|
const response_utils_1 = require("@naman_deep_singh/response-utils");
|
|
6
|
-
const
|
|
7
|
-
|
|
5
|
+
const AppError_1 = require("../../error/AppError");
|
|
6
|
+
const mapAppErrorToResponder_1 = require("../../utils/mapAppErrorToResponder");
|
|
7
|
+
function expressErrorHandler(err, req, res, next) {
|
|
8
8
|
const responder = new response_utils_1.ExpressResponder({}, res);
|
|
9
9
|
// AppError → known operational error
|
|
10
10
|
if (err instanceof AppError_1.AppError) {
|
|
11
11
|
return (0, mapAppErrorToResponder_1.mapAppErrorToResponder)(responder, err);
|
|
12
12
|
}
|
|
13
13
|
// Unexpected / programming / unknown error
|
|
14
|
-
console.error(
|
|
15
|
-
return responder.serverError(
|
|
16
|
-
details: process.env.NODE_ENV ===
|
|
14
|
+
console.error('UNEXPECTED ERROR:', err);
|
|
15
|
+
return responder.serverError('Internal server error', {
|
|
16
|
+
details: process.env.NODE_ENV === 'production' ? undefined : err,
|
|
17
17
|
});
|
|
18
18
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./errorHandler"), exports);
|
|
18
|
+
__exportStar(require("./errorConverter"), exports);
|
|
@@ -15,7 +15,9 @@ function mapAppErrorToResponder(responder, err) {
|
|
|
15
15
|
case response_utils_1.HTTP_STATUS.CLIENT_ERROR.CONFLICT:
|
|
16
16
|
return responder.conflict(err.message);
|
|
17
17
|
case response_utils_1.HTTP_STATUS.CLIENT_ERROR.UNPROCESSABLE_ENTITY:
|
|
18
|
-
return responder.unprocessableEntity(err.message, {
|
|
18
|
+
return responder.unprocessableEntity(err.message, {
|
|
19
|
+
details: err.details,
|
|
20
|
+
});
|
|
19
21
|
case response_utils_1.HTTP_STATUS.CLIENT_ERROR.TOO_MANY_REQUESTS:
|
|
20
22
|
return responder.tooManyRequests(err.message);
|
|
21
23
|
default:
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
export class AppError extends Error {
|
|
2
|
-
|
|
3
|
-
public isOperational: boolean;
|
|
4
|
-
public details?: any;
|
|
5
|
-
|
|
6
|
-
constructor(message: string, statusCode = 500, details?: any) {
|
|
2
|
+
constructor(message, statusCode = 500, details) {
|
|
7
3
|
super(message);
|
|
8
|
-
|
|
9
4
|
this.statusCode = statusCode;
|
|
10
5
|
this.isOperational = true;
|
|
11
6
|
this.details = details;
|
|
12
|
-
|
|
13
7
|
Error.captureStackTrace(this, this.constructor);
|
|
14
8
|
}
|
|
15
9
|
}
|
|
16
|
-
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './error/AppError';
|
|
2
|
+
export * from './error/HTTPError';
|
|
3
|
+
export * from './error/BadRequestError';
|
|
4
|
+
export * from './error/UnauthorizedError';
|
|
5
|
+
export * from './error/ForbiddenError';
|
|
6
|
+
export * from './error/NotFoundError';
|
|
7
|
+
export * from './error/ConflictError';
|
|
8
|
+
export * from './error/ValidationError';
|
|
9
|
+
export * from './error/InternalServerError';
|
|
10
|
+
export * from './middleware/express';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './error/AppError';
|
|
2
|
+
export * from './error/HTTPError';
|
|
3
|
+
export * from './error/BadRequestError';
|
|
4
|
+
export * from './error/UnauthorizedError';
|
|
5
|
+
export * from './error/ForbiddenError';
|
|
6
|
+
export * from './error/NotFoundError';
|
|
7
|
+
export * from './error/ConflictError';
|
|
8
|
+
export * from './error/ValidationError';
|
|
9
|
+
export * from './error/InternalServerError';
|
|
10
|
+
export * from './middleware/express';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { AppError } from '../../error/AppError';
|
|
2
|
+
export function errorConverter(err, req, res, next) {
|
|
3
|
+
if (err instanceof AppError) {
|
|
4
|
+
return next(err);
|
|
5
|
+
}
|
|
6
|
+
// Safely extract properties from unknown error
|
|
7
|
+
let message = 'Internal Error';
|
|
8
|
+
let statusCode = 500;
|
|
9
|
+
let details = undefined;
|
|
10
|
+
if (typeof err === 'object' && err !== null) {
|
|
11
|
+
const e = err;
|
|
12
|
+
if (typeof e.message === 'string')
|
|
13
|
+
message = e.message;
|
|
14
|
+
if (typeof e.statusCode === 'number')
|
|
15
|
+
statusCode = e.statusCode;
|
|
16
|
+
if ('details' in e)
|
|
17
|
+
details = e.details;
|
|
18
|
+
}
|
|
19
|
+
else if (typeof err === 'string') {
|
|
20
|
+
message = err;
|
|
21
|
+
}
|
|
22
|
+
const convertedError = new AppError(message, statusCode, details);
|
|
23
|
+
next(convertedError);
|
|
24
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ExpressResponder } from '@naman_deep_singh/response-utils';
|
|
2
|
+
import { AppError } from '../../error/AppError';
|
|
3
|
+
import { mapAppErrorToResponder } from '../../utils/mapAppErrorToResponder';
|
|
4
|
+
export function expressErrorHandler(err, req, res, next) {
|
|
5
|
+
const responder = new ExpressResponder({}, res);
|
|
6
|
+
// AppError → known operational error
|
|
7
|
+
if (err instanceof AppError) {
|
|
8
|
+
return mapAppErrorToResponder(responder, err);
|
|
9
|
+
}
|
|
10
|
+
// Unexpected / programming / unknown error
|
|
11
|
+
console.error('UNEXPECTED ERROR:', err);
|
|
12
|
+
return responder.serverError('Internal server error', {
|
|
13
|
+
details: process.env.NODE_ENV === 'production' ? undefined : err,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -1,29 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export function mapAppErrorToResponder(responder: ExpressResponder<any>, err: AppError) {
|
|
1
|
+
import { HTTP_STATUS } from '@naman_deep_singh/response-utils';
|
|
2
|
+
export function mapAppErrorToResponder(responder, err) {
|
|
5
3
|
switch (err.statusCode) {
|
|
6
4
|
case HTTP_STATUS.CLIENT_ERROR.BAD_REQUEST:
|
|
7
5
|
return responder.badRequest(err.message, { details: err.details });
|
|
8
|
-
|
|
9
6
|
case HTTP_STATUS.CLIENT_ERROR.UNAUTHORIZED:
|
|
10
7
|
return responder.unauthorized(err.message);
|
|
11
|
-
|
|
12
8
|
case HTTP_STATUS.CLIENT_ERROR.FORBIDDEN:
|
|
13
9
|
return responder.forbidden(err.message);
|
|
14
|
-
|
|
15
10
|
case HTTP_STATUS.CLIENT_ERROR.NOT_FOUND:
|
|
16
11
|
return responder.notFound(err.message);
|
|
17
|
-
|
|
18
12
|
case HTTP_STATUS.CLIENT_ERROR.CONFLICT:
|
|
19
13
|
return responder.conflict(err.message);
|
|
20
|
-
|
|
21
14
|
case HTTP_STATUS.CLIENT_ERROR.UNPROCESSABLE_ENTITY:
|
|
22
|
-
return responder.unprocessableEntity(err.message, {
|
|
23
|
-
|
|
15
|
+
return responder.unprocessableEntity(err.message, {
|
|
16
|
+
details: err.details,
|
|
17
|
+
});
|
|
24
18
|
case HTTP_STATUS.CLIENT_ERROR.TOO_MANY_REQUESTS:
|
|
25
19
|
return responder.tooManyRequests(err.message);
|
|
26
|
-
|
|
27
20
|
default:
|
|
28
21
|
// Any other custom status maps to a generic server error
|
|
29
22
|
return responder.serverError(err.message, { details: err.details });
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './error/AppError';
|
|
2
|
+
export * from './error/HTTPError';
|
|
3
|
+
export * from './error/BadRequestError';
|
|
4
|
+
export * from './error/UnauthorizedError';
|
|
5
|
+
export * from './error/ForbiddenError';
|
|
6
|
+
export * from './error/NotFoundError';
|
|
7
|
+
export * from './error/ConflictError';
|
|
8
|
+
export * from './error/ValidationError';
|
|
9
|
+
export * from './error/InternalServerError';
|
|
10
|
+
export * from './middleware/express';
|
package/package.json
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naman_deep_singh/errors-utils",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
"
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "Standardized error classes and Express middleware for consistent error handling with TypeScript",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/cjs/index.js",
|
|
7
|
+
"module": "./dist/esm/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/esm/index.js",
|
|
11
|
+
"require": "./dist/cjs/index.js",
|
|
12
|
+
"types": "./dist/types/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
7
20
|
"keywords": [
|
|
8
21
|
"errors"
|
|
9
22
|
],
|
|
@@ -13,12 +26,15 @@
|
|
|
13
26
|
"@types/express": "^5.0.5",
|
|
14
27
|
"@types/node": "^25.0.1",
|
|
15
28
|
"express": "^5.1.0",
|
|
16
|
-
"typescript": "^5.9.3"
|
|
29
|
+
"typescript": "^5.9.3",
|
|
30
|
+
"rimraf": "^5.0.5"
|
|
17
31
|
},
|
|
18
32
|
"dependencies": {
|
|
19
|
-
"@naman_deep_singh/response-utils": "^2.0.
|
|
33
|
+
"@naman_deep_singh/response-utils": "^2.0.4"
|
|
20
34
|
},
|
|
21
35
|
"scripts": {
|
|
22
|
-
"build": "tsc"
|
|
36
|
+
"build": "pnpm run build:types && tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json",
|
|
37
|
+
"build:types": "tsc -p tsconfig.base.json --emitDeclarationOnly --outDir dist/types",
|
|
38
|
+
"clean": "rimraf dist"
|
|
23
39
|
}
|
|
24
40
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export * from "./error/AppError";
|
|
2
|
-
export * from "./error/HTTPError";
|
|
3
|
-
export * from "./error/BadRequestError";
|
|
4
|
-
export * from "./error/UnauthorizedError";
|
|
5
|
-
export * from "./error/ForbiddenError";
|
|
6
|
-
export * from "./error/NotFoundError";
|
|
7
|
-
export * from "./error/ConflictError";
|
|
8
|
-
export * from "./error/ValidationError";
|
|
9
|
-
export * from "./error/InternalServerError";
|
|
10
|
-
export * from "./middleware/errorConverter";
|
|
11
|
-
export * from "./middleware/errorHandler";
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.errorConverter = errorConverter;
|
|
4
|
-
const AppError_1 = require("../error/AppError");
|
|
5
|
-
function errorConverter(err, req, res, next) {
|
|
6
|
-
if (err instanceof AppError_1.AppError) {
|
|
7
|
-
return next(err);
|
|
8
|
-
}
|
|
9
|
-
const convertedError = new AppError_1.AppError(err.message || "Internal Error", err.statusCode || 500, err.details || undefined);
|
|
10
|
-
next(convertedError);
|
|
11
|
-
}
|
package/src/error/HTTPError.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { AppError } from "./AppError";
|
|
2
|
-
|
|
3
|
-
export class HTTPError extends AppError {
|
|
4
|
-
public status: string;
|
|
5
|
-
|
|
6
|
-
constructor(message: string, statusCode: number, details?: any) {
|
|
7
|
-
super(message, statusCode, details);
|
|
8
|
-
|
|
9
|
-
this.status = `${statusCode}`.startsWith("4") ? "fail" : "error";
|
|
10
|
-
}
|
|
11
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export * from "./error/AppError";
|
|
2
|
-
export * from "./error/HTTPError";
|
|
3
|
-
export * from "./error/BadRequestError";
|
|
4
|
-
export * from "./error/UnauthorizedError";
|
|
5
|
-
export * from "./error/ForbiddenError";
|
|
6
|
-
export * from "./error/NotFoundError";
|
|
7
|
-
export * from "./error/ConflictError";
|
|
8
|
-
export * from "./error/ValidationError";
|
|
9
|
-
export * from "./error/InternalServerError";
|
|
10
|
-
|
|
11
|
-
export * from "./middleware/errorConverter";
|
|
12
|
-
export * from "./middleware/errorHandler";
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from "express";
|
|
2
|
-
import { AppError } from "../error/AppError";
|
|
3
|
-
|
|
4
|
-
export function errorConverter(err: any, req: Request, res: Response, next: NextFunction) {
|
|
5
|
-
if (err instanceof AppError) {
|
|
6
|
-
return next(err);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const convertedError = new AppError(
|
|
10
|
-
err.message || "Internal Error",
|
|
11
|
-
err.statusCode || 500,
|
|
12
|
-
err.details || undefined
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
next(convertedError);
|
|
16
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { Request, Response, NextFunction } from "express";
|
|
2
|
-
import { AppError } from "../error/AppError";
|
|
3
|
-
import { ExpressResponder } from "@naman_deep_singh/response-utils";
|
|
4
|
-
import { mapAppErrorToResponder } from "src/utils/mapAppErrorToResponder";
|
|
5
|
-
|
|
6
|
-
export function errorHandler(
|
|
7
|
-
err: unknown,
|
|
8
|
-
req: Request,
|
|
9
|
-
res: Response,
|
|
10
|
-
next: NextFunction
|
|
11
|
-
) {
|
|
12
|
-
const responder = new ExpressResponder({}, res);
|
|
13
|
-
|
|
14
|
-
// AppError → known operational error
|
|
15
|
-
if (err instanceof AppError) {
|
|
16
|
-
return mapAppErrorToResponder(responder, err);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Unexpected / programming / unknown error
|
|
20
|
-
console.error("UNEXPECTED ERROR:", err);
|
|
21
|
-
|
|
22
|
-
return responder.serverError("Internal server error", {
|
|
23
|
-
details: process.env.NODE_ENV === "production" ? undefined : err,
|
|
24
|
-
});
|
|
25
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "CommonJS",
|
|
5
|
-
"moduleResolution": "node",
|
|
6
|
-
"rootDir": "./src",
|
|
7
|
-
"outDir": "./dist",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"allowSyntheticDefaultImports": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"forceConsistentCasingInFileNames": true,
|
|
13
|
-
"declaration": true,
|
|
14
|
-
"baseUrl": ".",
|
|
15
|
-
"paths": {
|
|
16
|
-
"*": ["*", "*.ts", "*.js"]
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"include": ["src/**/*"],
|
|
20
|
-
"exclude": ["node_modules", "dist"]
|
|
21
|
-
}
|
|
File without changes
|