@perkos/util-errors 1.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 +93 -0
- package/dist/index.d.mts +126 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.js +193 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +157 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# @perkos/util-errors
|
|
2
|
+
|
|
3
|
+
Error handling utilities and classes for vendor services with Zod integration.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @perkos/util-errors
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import {
|
|
15
|
+
AppError,
|
|
16
|
+
ValidationError,
|
|
17
|
+
PaymentError,
|
|
18
|
+
formatErrorResponse,
|
|
19
|
+
getErrorStatusCode,
|
|
20
|
+
} from "@perkos/util-errors";
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
|
|
23
|
+
// Throw application errors with context
|
|
24
|
+
throw new AppError("Something went wrong", 500, true, { userId: "123" });
|
|
25
|
+
|
|
26
|
+
// Throw validation errors
|
|
27
|
+
throw new ValidationError("Invalid input", [{ field: "email", message: "Required" }]);
|
|
28
|
+
|
|
29
|
+
// Create from Zod errors
|
|
30
|
+
try {
|
|
31
|
+
schema.parse(data);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (error instanceof z.ZodError) {
|
|
34
|
+
throw ValidationError.fromZodError(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Payment errors for x402
|
|
39
|
+
throw new PaymentError("Payment failed", "Insufficient funds");
|
|
40
|
+
|
|
41
|
+
// Format errors for API response
|
|
42
|
+
const response = formatErrorResponse(error);
|
|
43
|
+
const statusCode = getErrorStatusCode(error);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Error Classes
|
|
47
|
+
|
|
48
|
+
### `AppError`
|
|
49
|
+
Base error class with HTTP status code and context.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
new AppError(message, statusCode?, isOperational?, context?)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### `ValidationError`
|
|
56
|
+
For request validation failures with Zod integration.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
new ValidationError(message?, details?)
|
|
60
|
+
ValidationError.fromZodError(zodError)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### `PaymentError`
|
|
64
|
+
For x402 payment-related failures.
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
new PaymentError(message, reason?, transactionHash?, context?)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Other Errors
|
|
71
|
+
- `NotFoundError` (404)
|
|
72
|
+
- `UnauthorizedError` (401)
|
|
73
|
+
- `ForbiddenError` (403)
|
|
74
|
+
- `RateLimitError` (429)
|
|
75
|
+
- `ServiceUnavailableError` (503)
|
|
76
|
+
|
|
77
|
+
## Utilities
|
|
78
|
+
|
|
79
|
+
### `formatErrorResponse(error)`
|
|
80
|
+
Format any error for API response.
|
|
81
|
+
|
|
82
|
+
### `getErrorStatusCode(error)`
|
|
83
|
+
Get HTTP status code from any error.
|
|
84
|
+
|
|
85
|
+
### `isOperationalError(error)`
|
|
86
|
+
Check if error is operational (expected) vs programming error.
|
|
87
|
+
|
|
88
|
+
### `createErrorHandler(options?)`
|
|
89
|
+
Create error handler middleware.
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { ZodError } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @perkos/error-handling
|
|
5
|
+
* Error handling utilities and classes for vendor services
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Base application error class
|
|
10
|
+
* Extends Error with HTTP status code and context
|
|
11
|
+
*/
|
|
12
|
+
declare class AppError extends Error {
|
|
13
|
+
readonly statusCode: number;
|
|
14
|
+
readonly isOperational: boolean;
|
|
15
|
+
readonly context?: Record<string, any>;
|
|
16
|
+
constructor(message: string, statusCode?: number, isOperational?: boolean, context?: Record<string, any>);
|
|
17
|
+
toJSON(): {
|
|
18
|
+
error: string;
|
|
19
|
+
statusCode: number;
|
|
20
|
+
context: Record<string, any> | undefined;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Validation error class
|
|
25
|
+
* For request validation failures with Zod integration
|
|
26
|
+
*/
|
|
27
|
+
declare class ValidationError extends AppError {
|
|
28
|
+
readonly details?: any;
|
|
29
|
+
constructor(message?: string, details?: any);
|
|
30
|
+
/**
|
|
31
|
+
* Create ValidationError from ZodError
|
|
32
|
+
*/
|
|
33
|
+
static fromZodError(error: ZodError): ValidationError;
|
|
34
|
+
toJSON(): {
|
|
35
|
+
error: string;
|
|
36
|
+
details: any;
|
|
37
|
+
statusCode: number;
|
|
38
|
+
context: Record<string, any> | undefined;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Payment error class
|
|
43
|
+
* For x402 payment-related failures
|
|
44
|
+
*/
|
|
45
|
+
declare class PaymentError extends AppError {
|
|
46
|
+
readonly reason?: string;
|
|
47
|
+
readonly transactionHash?: string;
|
|
48
|
+
constructor(message: string, reason?: string, transactionHash?: string, context?: Record<string, any>);
|
|
49
|
+
toJSON(): {
|
|
50
|
+
error: string;
|
|
51
|
+
reason: string | undefined;
|
|
52
|
+
transactionHash: string | undefined;
|
|
53
|
+
statusCode: number;
|
|
54
|
+
context: Record<string, any> | undefined;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Not found error class
|
|
59
|
+
*/
|
|
60
|
+
declare class NotFoundError extends AppError {
|
|
61
|
+
constructor(message?: string, context?: Record<string, any>);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Unauthorized error class
|
|
65
|
+
*/
|
|
66
|
+
declare class UnauthorizedError extends AppError {
|
|
67
|
+
constructor(message?: string, context?: Record<string, any>);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Forbidden error class
|
|
71
|
+
*/
|
|
72
|
+
declare class ForbiddenError extends AppError {
|
|
73
|
+
constructor(message?: string, context?: Record<string, any>);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Rate limit error class
|
|
77
|
+
*/
|
|
78
|
+
declare class RateLimitError extends AppError {
|
|
79
|
+
readonly retryAfter?: number;
|
|
80
|
+
constructor(message?: string, retryAfter?: number, context?: Record<string, any>);
|
|
81
|
+
toJSON(): {
|
|
82
|
+
error: string;
|
|
83
|
+
retryAfter: number | undefined;
|
|
84
|
+
statusCode: number;
|
|
85
|
+
context: Record<string, any> | undefined;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Service unavailable error class
|
|
90
|
+
*/
|
|
91
|
+
declare class ServiceUnavailableError extends AppError {
|
|
92
|
+
constructor(message?: string, context?: Record<string, any>);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if error is operational (expected) or programming error
|
|
96
|
+
*/
|
|
97
|
+
declare function isOperationalError(error: Error): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Error response formatter for API responses
|
|
100
|
+
*/
|
|
101
|
+
interface ErrorResponse {
|
|
102
|
+
error: string;
|
|
103
|
+
message?: string;
|
|
104
|
+
details?: any;
|
|
105
|
+
statusCode: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Format error for API response
|
|
109
|
+
*/
|
|
110
|
+
declare function formatErrorResponse(error: unknown): ErrorResponse;
|
|
111
|
+
/**
|
|
112
|
+
* Get HTTP status code from error
|
|
113
|
+
*/
|
|
114
|
+
declare function getErrorStatusCode(error: unknown): number;
|
|
115
|
+
/**
|
|
116
|
+
* Create error handler middleware (framework-agnostic)
|
|
117
|
+
*/
|
|
118
|
+
declare function createErrorHandler(options?: {
|
|
119
|
+
logger?: (error: Error, context?: Record<string, any>) => void;
|
|
120
|
+
includeStack?: boolean;
|
|
121
|
+
}): (error: unknown) => {
|
|
122
|
+
response: ErrorResponse;
|
|
123
|
+
statusCode: number;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export { AppError, type ErrorResponse, ForbiddenError, NotFoundError, PaymentError, RateLimitError, ServiceUnavailableError, UnauthorizedError, ValidationError, createErrorHandler, formatErrorResponse, getErrorStatusCode, isOperationalError };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { ZodError } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @perkos/error-handling
|
|
5
|
+
* Error handling utilities and classes for vendor services
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Base application error class
|
|
10
|
+
* Extends Error with HTTP status code and context
|
|
11
|
+
*/
|
|
12
|
+
declare class AppError extends Error {
|
|
13
|
+
readonly statusCode: number;
|
|
14
|
+
readonly isOperational: boolean;
|
|
15
|
+
readonly context?: Record<string, any>;
|
|
16
|
+
constructor(message: string, statusCode?: number, isOperational?: boolean, context?: Record<string, any>);
|
|
17
|
+
toJSON(): {
|
|
18
|
+
error: string;
|
|
19
|
+
statusCode: number;
|
|
20
|
+
context: Record<string, any> | undefined;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Validation error class
|
|
25
|
+
* For request validation failures with Zod integration
|
|
26
|
+
*/
|
|
27
|
+
declare class ValidationError extends AppError {
|
|
28
|
+
readonly details?: any;
|
|
29
|
+
constructor(message?: string, details?: any);
|
|
30
|
+
/**
|
|
31
|
+
* Create ValidationError from ZodError
|
|
32
|
+
*/
|
|
33
|
+
static fromZodError(error: ZodError): ValidationError;
|
|
34
|
+
toJSON(): {
|
|
35
|
+
error: string;
|
|
36
|
+
details: any;
|
|
37
|
+
statusCode: number;
|
|
38
|
+
context: Record<string, any> | undefined;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Payment error class
|
|
43
|
+
* For x402 payment-related failures
|
|
44
|
+
*/
|
|
45
|
+
declare class PaymentError extends AppError {
|
|
46
|
+
readonly reason?: string;
|
|
47
|
+
readonly transactionHash?: string;
|
|
48
|
+
constructor(message: string, reason?: string, transactionHash?: string, context?: Record<string, any>);
|
|
49
|
+
toJSON(): {
|
|
50
|
+
error: string;
|
|
51
|
+
reason: string | undefined;
|
|
52
|
+
transactionHash: string | undefined;
|
|
53
|
+
statusCode: number;
|
|
54
|
+
context: Record<string, any> | undefined;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Not found error class
|
|
59
|
+
*/
|
|
60
|
+
declare class NotFoundError extends AppError {
|
|
61
|
+
constructor(message?: string, context?: Record<string, any>);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Unauthorized error class
|
|
65
|
+
*/
|
|
66
|
+
declare class UnauthorizedError extends AppError {
|
|
67
|
+
constructor(message?: string, context?: Record<string, any>);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Forbidden error class
|
|
71
|
+
*/
|
|
72
|
+
declare class ForbiddenError extends AppError {
|
|
73
|
+
constructor(message?: string, context?: Record<string, any>);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Rate limit error class
|
|
77
|
+
*/
|
|
78
|
+
declare class RateLimitError extends AppError {
|
|
79
|
+
readonly retryAfter?: number;
|
|
80
|
+
constructor(message?: string, retryAfter?: number, context?: Record<string, any>);
|
|
81
|
+
toJSON(): {
|
|
82
|
+
error: string;
|
|
83
|
+
retryAfter: number | undefined;
|
|
84
|
+
statusCode: number;
|
|
85
|
+
context: Record<string, any> | undefined;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Service unavailable error class
|
|
90
|
+
*/
|
|
91
|
+
declare class ServiceUnavailableError extends AppError {
|
|
92
|
+
constructor(message?: string, context?: Record<string, any>);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if error is operational (expected) or programming error
|
|
96
|
+
*/
|
|
97
|
+
declare function isOperationalError(error: Error): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Error response formatter for API responses
|
|
100
|
+
*/
|
|
101
|
+
interface ErrorResponse {
|
|
102
|
+
error: string;
|
|
103
|
+
message?: string;
|
|
104
|
+
details?: any;
|
|
105
|
+
statusCode: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Format error for API response
|
|
109
|
+
*/
|
|
110
|
+
declare function formatErrorResponse(error: unknown): ErrorResponse;
|
|
111
|
+
/**
|
|
112
|
+
* Get HTTP status code from error
|
|
113
|
+
*/
|
|
114
|
+
declare function getErrorStatusCode(error: unknown): number;
|
|
115
|
+
/**
|
|
116
|
+
* Create error handler middleware (framework-agnostic)
|
|
117
|
+
*/
|
|
118
|
+
declare function createErrorHandler(options?: {
|
|
119
|
+
logger?: (error: Error, context?: Record<string, any>) => void;
|
|
120
|
+
includeStack?: boolean;
|
|
121
|
+
}): (error: unknown) => {
|
|
122
|
+
response: ErrorResponse;
|
|
123
|
+
statusCode: number;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export { AppError, type ErrorResponse, ForbiddenError, NotFoundError, PaymentError, RateLimitError, ServiceUnavailableError, UnauthorizedError, ValidationError, createErrorHandler, formatErrorResponse, getErrorStatusCode, isOperationalError };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
AppError: () => AppError,
|
|
24
|
+
ForbiddenError: () => ForbiddenError,
|
|
25
|
+
NotFoundError: () => NotFoundError,
|
|
26
|
+
PaymentError: () => PaymentError,
|
|
27
|
+
RateLimitError: () => RateLimitError,
|
|
28
|
+
ServiceUnavailableError: () => ServiceUnavailableError,
|
|
29
|
+
UnauthorizedError: () => UnauthorizedError,
|
|
30
|
+
ValidationError: () => ValidationError,
|
|
31
|
+
createErrorHandler: () => createErrorHandler,
|
|
32
|
+
formatErrorResponse: () => formatErrorResponse,
|
|
33
|
+
getErrorStatusCode: () => getErrorStatusCode,
|
|
34
|
+
isOperationalError: () => isOperationalError
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
var import_zod = require("zod");
|
|
38
|
+
var AppError = class extends Error {
|
|
39
|
+
constructor(message, statusCode = 500, isOperational = true, context) {
|
|
40
|
+
super(message);
|
|
41
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
42
|
+
this.name = this.constructor.name;
|
|
43
|
+
this.statusCode = statusCode;
|
|
44
|
+
this.isOperational = isOperational;
|
|
45
|
+
this.context = context;
|
|
46
|
+
Error.captureStackTrace(this);
|
|
47
|
+
}
|
|
48
|
+
toJSON() {
|
|
49
|
+
return {
|
|
50
|
+
error: this.message,
|
|
51
|
+
statusCode: this.statusCode,
|
|
52
|
+
context: this.context
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var ValidationError = class _ValidationError extends AppError {
|
|
57
|
+
constructor(message = "Validation failed", details) {
|
|
58
|
+
super(message, 400, true, { details });
|
|
59
|
+
this.details = details;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Create ValidationError from ZodError
|
|
63
|
+
*/
|
|
64
|
+
static fromZodError(error) {
|
|
65
|
+
const details = error.errors.map((e) => ({
|
|
66
|
+
path: e.path.join("."),
|
|
67
|
+
message: e.message,
|
|
68
|
+
code: e.code
|
|
69
|
+
}));
|
|
70
|
+
return new _ValidationError("Validation error", details);
|
|
71
|
+
}
|
|
72
|
+
toJSON() {
|
|
73
|
+
return {
|
|
74
|
+
error: this.message,
|
|
75
|
+
details: this.details,
|
|
76
|
+
statusCode: this.statusCode,
|
|
77
|
+
context: this.context
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
var PaymentError = class extends AppError {
|
|
82
|
+
constructor(message, reason, transactionHash, context) {
|
|
83
|
+
super(message, 402, true, context);
|
|
84
|
+
this.reason = reason;
|
|
85
|
+
this.transactionHash = transactionHash;
|
|
86
|
+
}
|
|
87
|
+
toJSON() {
|
|
88
|
+
return {
|
|
89
|
+
error: this.message,
|
|
90
|
+
reason: this.reason,
|
|
91
|
+
transactionHash: this.transactionHash,
|
|
92
|
+
statusCode: this.statusCode,
|
|
93
|
+
context: this.context
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
var NotFoundError = class extends AppError {
|
|
98
|
+
constructor(message = "Resource not found", context) {
|
|
99
|
+
super(message, 404, true, context);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
var UnauthorizedError = class extends AppError {
|
|
103
|
+
constructor(message = "Unauthorized", context) {
|
|
104
|
+
super(message, 401, true, context);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var ForbiddenError = class extends AppError {
|
|
108
|
+
constructor(message = "Forbidden", context) {
|
|
109
|
+
super(message, 403, true, context);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
var RateLimitError = class extends AppError {
|
|
113
|
+
constructor(message = "Rate limit exceeded", retryAfter, context) {
|
|
114
|
+
super(message, 429, true, context);
|
|
115
|
+
this.retryAfter = retryAfter;
|
|
116
|
+
}
|
|
117
|
+
toJSON() {
|
|
118
|
+
return {
|
|
119
|
+
error: this.message,
|
|
120
|
+
retryAfter: this.retryAfter,
|
|
121
|
+
statusCode: this.statusCode,
|
|
122
|
+
context: this.context
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
var ServiceUnavailableError = class extends AppError {
|
|
127
|
+
constructor(message = "Service unavailable", context) {
|
|
128
|
+
super(message, 503, true, context);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
function isOperationalError(error) {
|
|
132
|
+
if (error instanceof AppError) {
|
|
133
|
+
return error.isOperational;
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
function formatErrorResponse(error) {
|
|
138
|
+
if (error instanceof import_zod.ZodError) {
|
|
139
|
+
const validationError = ValidationError.fromZodError(error);
|
|
140
|
+
return validationError.toJSON();
|
|
141
|
+
}
|
|
142
|
+
if (error instanceof AppError) {
|
|
143
|
+
return error.toJSON();
|
|
144
|
+
}
|
|
145
|
+
if (error instanceof Error) {
|
|
146
|
+
return {
|
|
147
|
+
error: error.message,
|
|
148
|
+
statusCode: 500
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
error: "Unknown error",
|
|
153
|
+
statusCode: 500
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function getErrorStatusCode(error) {
|
|
157
|
+
if (error instanceof AppError) {
|
|
158
|
+
return error.statusCode;
|
|
159
|
+
}
|
|
160
|
+
if (error instanceof import_zod.ZodError) {
|
|
161
|
+
return 400;
|
|
162
|
+
}
|
|
163
|
+
return 500;
|
|
164
|
+
}
|
|
165
|
+
function createErrorHandler(options) {
|
|
166
|
+
return (error) => {
|
|
167
|
+
const response = formatErrorResponse(error);
|
|
168
|
+
const statusCode = getErrorStatusCode(error);
|
|
169
|
+
if (options?.logger && error instanceof Error) {
|
|
170
|
+
options.logger(error, { statusCode });
|
|
171
|
+
}
|
|
172
|
+
if (options?.includeStack && error instanceof Error) {
|
|
173
|
+
response.stack = error.stack;
|
|
174
|
+
}
|
|
175
|
+
return { response, statusCode };
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
179
|
+
0 && (module.exports = {
|
|
180
|
+
AppError,
|
|
181
|
+
ForbiddenError,
|
|
182
|
+
NotFoundError,
|
|
183
|
+
PaymentError,
|
|
184
|
+
RateLimitError,
|
|
185
|
+
ServiceUnavailableError,
|
|
186
|
+
UnauthorizedError,
|
|
187
|
+
ValidationError,
|
|
188
|
+
createErrorHandler,
|
|
189
|
+
formatErrorResponse,
|
|
190
|
+
getErrorStatusCode,
|
|
191
|
+
isOperationalError
|
|
192
|
+
});
|
|
193
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @perkos/error-handling\n * Error handling utilities and classes for vendor services\n */\n\nimport { ZodError } from \"zod\";\n\n/**\n * Base application error class\n * Extends Error with HTTP status code and context\n */\nexport class AppError extends Error {\n public readonly statusCode: number;\n public readonly isOperational: boolean;\n public readonly context?: Record<string, any>;\n\n constructor(\n message: string,\n statusCode: number = 500,\n isOperational: boolean = true,\n context?: Record<string, any>\n ) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n\n this.name = this.constructor.name;\n this.statusCode = statusCode;\n this.isOperational = isOperational;\n this.context = context;\n\n Error.captureStackTrace(this);\n }\n\n toJSON() {\n return {\n error: this.message,\n statusCode: this.statusCode,\n context: this.context,\n };\n }\n}\n\n/**\n * Validation error class\n * For request validation failures with Zod integration\n */\nexport class ValidationError extends AppError {\n public readonly details?: any;\n\n constructor(message: string = \"Validation failed\", details?: any) {\n super(message, 400, true, { details });\n this.details = details;\n }\n\n /**\n * Create ValidationError from ZodError\n */\n static fromZodError(error: ZodError): ValidationError {\n const details = error.errors.map((e) => ({\n path: e.path.join(\".\"),\n message: e.message,\n code: e.code,\n }));\n return new ValidationError(\"Validation error\", details);\n }\n\n toJSON() {\n return {\n error: this.message,\n details: this.details,\n statusCode: this.statusCode,\n context: this.context,\n };\n }\n}\n\n/**\n * Payment error class\n * For x402 payment-related failures\n */\nexport class PaymentError extends AppError {\n public readonly reason?: string;\n public readonly transactionHash?: string;\n\n constructor(\n message: string,\n reason?: string,\n transactionHash?: string,\n context?: Record<string, any>\n ) {\n super(message, 402, true, context);\n this.reason = reason;\n this.transactionHash = transactionHash;\n }\n\n toJSON() {\n return {\n error: this.message,\n reason: this.reason,\n transactionHash: this.transactionHash,\n statusCode: this.statusCode,\n context: this.context,\n };\n }\n}\n\n/**\n * Not found error class\n */\nexport class NotFoundError extends AppError {\n constructor(message: string = \"Resource not found\", context?: Record<string, any>) {\n super(message, 404, true, context);\n }\n}\n\n/**\n * Unauthorized error class\n */\nexport class UnauthorizedError extends AppError {\n constructor(message: string = \"Unauthorized\", context?: Record<string, any>) {\n super(message, 401, true, context);\n }\n}\n\n/**\n * Forbidden error class\n */\nexport class ForbiddenError extends AppError {\n constructor(message: string = \"Forbidden\", context?: Record<string, any>) {\n super(message, 403, true, context);\n }\n}\n\n/**\n * Rate limit error class\n */\nexport class RateLimitError extends AppError {\n public readonly retryAfter?: number;\n\n constructor(\n message: string = \"Rate limit exceeded\",\n retryAfter?: number,\n context?: Record<string, any>\n ) {\n super(message, 429, true, context);\n this.retryAfter = retryAfter;\n }\n\n toJSON() {\n return {\n error: this.message,\n retryAfter: this.retryAfter,\n statusCode: this.statusCode,\n context: this.context,\n };\n }\n}\n\n/**\n * Service unavailable error class\n */\nexport class ServiceUnavailableError extends AppError {\n constructor(message: string = \"Service unavailable\", context?: Record<string, any>) {\n super(message, 503, true, context);\n }\n}\n\n/**\n * Check if error is operational (expected) or programming error\n */\nexport function isOperationalError(error: Error): boolean {\n if (error instanceof AppError) {\n return error.isOperational;\n }\n return false;\n}\n\n/**\n * Error response formatter for API responses\n */\nexport interface ErrorResponse {\n error: string;\n message?: string;\n details?: any;\n statusCode: number;\n}\n\n/**\n * Format error for API response\n */\nexport function formatErrorResponse(error: unknown): ErrorResponse {\n if (error instanceof ZodError) {\n const validationError = ValidationError.fromZodError(error);\n return validationError.toJSON() as ErrorResponse;\n }\n\n if (error instanceof AppError) {\n return error.toJSON() as ErrorResponse;\n }\n\n if (error instanceof Error) {\n return {\n error: error.message,\n statusCode: 500,\n };\n }\n\n return {\n error: \"Unknown error\",\n statusCode: 500,\n };\n}\n\n/**\n * Get HTTP status code from error\n */\nexport function getErrorStatusCode(error: unknown): number {\n if (error instanceof AppError) {\n return error.statusCode;\n }\n if (error instanceof ZodError) {\n return 400;\n }\n return 500;\n}\n\n/**\n * Create error handler middleware (framework-agnostic)\n */\nexport function createErrorHandler(options?: {\n logger?: (error: Error, context?: Record<string, any>) => void;\n includeStack?: boolean;\n}) {\n return (error: unknown) => {\n const response = formatErrorResponse(error);\n const statusCode = getErrorStatusCode(error);\n\n if (options?.logger && error instanceof Error) {\n options.logger(error, { statusCode });\n }\n\n if (options?.includeStack && error instanceof Error) {\n (response as any).stack = error.stack;\n }\n\n return { response, statusCode };\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,iBAAyB;AAMlB,IAAM,WAAN,cAAuB,MAAM;AAAA,EAKlC,YACE,SACA,aAAqB,KACrB,gBAAyB,MACzB,SACA;AACA,UAAM,OAAO;AACb,WAAO,eAAe,MAAM,WAAW,SAAS;AAEhD,SAAK,OAAO,KAAK,YAAY;AAC7B,SAAK,aAAa;AAClB,SAAK,gBAAgB;AACrB,SAAK,UAAU;AAEf,UAAM,kBAAkB,IAAI;AAAA,EAC9B;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK;AAAA,MACjB,SAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACF;AAMO,IAAM,kBAAN,MAAM,yBAAwB,SAAS;AAAA,EAG5C,YAAY,UAAkB,qBAAqB,SAAe;AAChE,UAAM,SAAS,KAAK,MAAM,EAAE,QAAQ,CAAC;AACrC,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,aAAa,OAAkC;AACpD,UAAM,UAAU,MAAM,OAAO,IAAI,CAAC,OAAO;AAAA,MACvC,MAAM,EAAE,KAAK,KAAK,GAAG;AAAA,MACrB,SAAS,EAAE;AAAA,MACX,MAAM,EAAE;AAAA,IACV,EAAE;AACF,WAAO,IAAI,iBAAgB,oBAAoB,OAAO;AAAA,EACxD;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,YAAY,KAAK;AAAA,MACjB,SAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACF;AAMO,IAAM,eAAN,cAA2B,SAAS;AAAA,EAIzC,YACE,SACA,QACA,iBACA,SACA;AACA,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,SAAK,SAAS;AACd,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,iBAAiB,KAAK;AAAA,MACtB,YAAY,KAAK;AAAA,MACjB,SAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACF;AAKO,IAAM,gBAAN,cAA4B,SAAS;AAAA,EAC1C,YAAY,UAAkB,sBAAsB,SAA+B;AACjF,UAAM,SAAS,KAAK,MAAM,OAAO;AAAA,EACnC;AACF;AAKO,IAAM,oBAAN,cAAgC,SAAS;AAAA,EAC9C,YAAY,UAAkB,gBAAgB,SAA+B;AAC3E,UAAM,SAAS,KAAK,MAAM,OAAO;AAAA,EACnC;AACF;AAKO,IAAM,iBAAN,cAA6B,SAAS;AAAA,EAC3C,YAAY,UAAkB,aAAa,SAA+B;AACxE,UAAM,SAAS,KAAK,MAAM,OAAO;AAAA,EACnC;AACF;AAKO,IAAM,iBAAN,cAA6B,SAAS;AAAA,EAG3C,YACE,UAAkB,uBAClB,YACA,SACA;AACA,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK;AAAA,MACjB,YAAY,KAAK;AAAA,MACjB,SAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACF;AAKO,IAAM,0BAAN,cAAsC,SAAS;AAAA,EACpD,YAAY,UAAkB,uBAAuB,SAA+B;AAClF,UAAM,SAAS,KAAK,MAAM,OAAO;AAAA,EACnC;AACF;AAKO,SAAS,mBAAmB,OAAuB;AACxD,MAAI,iBAAiB,UAAU;AAC7B,WAAO,MAAM;AAAA,EACf;AACA,SAAO;AACT;AAeO,SAAS,oBAAoB,OAA+B;AACjE,MAAI,iBAAiB,qBAAU;AAC7B,UAAM,kBAAkB,gBAAgB,aAAa,KAAK;AAC1D,WAAO,gBAAgB,OAAO;AAAA,EAChC;AAEA,MAAI,iBAAiB,UAAU;AAC7B,WAAO,MAAM,OAAO;AAAA,EACtB;AAEA,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,MACL,OAAO,MAAM;AAAA,MACb,YAAY;AAAA,IACd;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,YAAY;AAAA,EACd;AACF;AAKO,SAAS,mBAAmB,OAAwB;AACzD,MAAI,iBAAiB,UAAU;AAC7B,WAAO,MAAM;AAAA,EACf;AACA,MAAI,iBAAiB,qBAAU;AAC7B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKO,SAAS,mBAAmB,SAGhC;AACD,SAAO,CAAC,UAAmB;AACzB,UAAM,WAAW,oBAAoB,KAAK;AAC1C,UAAM,aAAa,mBAAmB,KAAK;AAE3C,QAAI,SAAS,UAAU,iBAAiB,OAAO;AAC7C,cAAQ,OAAO,OAAO,EAAE,WAAW,CAAC;AAAA,IACtC;AAEA,QAAI,SAAS,gBAAgB,iBAAiB,OAAO;AACnD,MAAC,SAAiB,QAAQ,MAAM;AAAA,IAClC;AAEA,WAAO,EAAE,UAAU,WAAW;AAAA,EAChC;AACF;","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { ZodError } from "zod";
|
|
3
|
+
var AppError = class extends Error {
|
|
4
|
+
constructor(message, statusCode = 500, isOperational = true, context) {
|
|
5
|
+
super(message);
|
|
6
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
7
|
+
this.name = this.constructor.name;
|
|
8
|
+
this.statusCode = statusCode;
|
|
9
|
+
this.isOperational = isOperational;
|
|
10
|
+
this.context = context;
|
|
11
|
+
Error.captureStackTrace(this);
|
|
12
|
+
}
|
|
13
|
+
toJSON() {
|
|
14
|
+
return {
|
|
15
|
+
error: this.message,
|
|
16
|
+
statusCode: this.statusCode,
|
|
17
|
+
context: this.context
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var ValidationError = class _ValidationError extends AppError {
|
|
22
|
+
constructor(message = "Validation failed", details) {
|
|
23
|
+
super(message, 400, true, { details });
|
|
24
|
+
this.details = details;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create ValidationError from ZodError
|
|
28
|
+
*/
|
|
29
|
+
static fromZodError(error) {
|
|
30
|
+
const details = error.errors.map((e) => ({
|
|
31
|
+
path: e.path.join("."),
|
|
32
|
+
message: e.message,
|
|
33
|
+
code: e.code
|
|
34
|
+
}));
|
|
35
|
+
return new _ValidationError("Validation error", details);
|
|
36
|
+
}
|
|
37
|
+
toJSON() {
|
|
38
|
+
return {
|
|
39
|
+
error: this.message,
|
|
40
|
+
details: this.details,
|
|
41
|
+
statusCode: this.statusCode,
|
|
42
|
+
context: this.context
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var PaymentError = class extends AppError {
|
|
47
|
+
constructor(message, reason, transactionHash, context) {
|
|
48
|
+
super(message, 402, true, context);
|
|
49
|
+
this.reason = reason;
|
|
50
|
+
this.transactionHash = transactionHash;
|
|
51
|
+
}
|
|
52
|
+
toJSON() {
|
|
53
|
+
return {
|
|
54
|
+
error: this.message,
|
|
55
|
+
reason: this.reason,
|
|
56
|
+
transactionHash: this.transactionHash,
|
|
57
|
+
statusCode: this.statusCode,
|
|
58
|
+
context: this.context
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var NotFoundError = class extends AppError {
|
|
63
|
+
constructor(message = "Resource not found", context) {
|
|
64
|
+
super(message, 404, true, context);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var UnauthorizedError = class extends AppError {
|
|
68
|
+
constructor(message = "Unauthorized", context) {
|
|
69
|
+
super(message, 401, true, context);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var ForbiddenError = class extends AppError {
|
|
73
|
+
constructor(message = "Forbidden", context) {
|
|
74
|
+
super(message, 403, true, context);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
var RateLimitError = class extends AppError {
|
|
78
|
+
constructor(message = "Rate limit exceeded", retryAfter, context) {
|
|
79
|
+
super(message, 429, true, context);
|
|
80
|
+
this.retryAfter = retryAfter;
|
|
81
|
+
}
|
|
82
|
+
toJSON() {
|
|
83
|
+
return {
|
|
84
|
+
error: this.message,
|
|
85
|
+
retryAfter: this.retryAfter,
|
|
86
|
+
statusCode: this.statusCode,
|
|
87
|
+
context: this.context
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
var ServiceUnavailableError = class extends AppError {
|
|
92
|
+
constructor(message = "Service unavailable", context) {
|
|
93
|
+
super(message, 503, true, context);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
function isOperationalError(error) {
|
|
97
|
+
if (error instanceof AppError) {
|
|
98
|
+
return error.isOperational;
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
function formatErrorResponse(error) {
|
|
103
|
+
if (error instanceof ZodError) {
|
|
104
|
+
const validationError = ValidationError.fromZodError(error);
|
|
105
|
+
return validationError.toJSON();
|
|
106
|
+
}
|
|
107
|
+
if (error instanceof AppError) {
|
|
108
|
+
return error.toJSON();
|
|
109
|
+
}
|
|
110
|
+
if (error instanceof Error) {
|
|
111
|
+
return {
|
|
112
|
+
error: error.message,
|
|
113
|
+
statusCode: 500
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
error: "Unknown error",
|
|
118
|
+
statusCode: 500
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function getErrorStatusCode(error) {
|
|
122
|
+
if (error instanceof AppError) {
|
|
123
|
+
return error.statusCode;
|
|
124
|
+
}
|
|
125
|
+
if (error instanceof ZodError) {
|
|
126
|
+
return 400;
|
|
127
|
+
}
|
|
128
|
+
return 500;
|
|
129
|
+
}
|
|
130
|
+
function createErrorHandler(options) {
|
|
131
|
+
return (error) => {
|
|
132
|
+
const response = formatErrorResponse(error);
|
|
133
|
+
const statusCode = getErrorStatusCode(error);
|
|
134
|
+
if (options?.logger && error instanceof Error) {
|
|
135
|
+
options.logger(error, { statusCode });
|
|
136
|
+
}
|
|
137
|
+
if (options?.includeStack && error instanceof Error) {
|
|
138
|
+
response.stack = error.stack;
|
|
139
|
+
}
|
|
140
|
+
return { response, statusCode };
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export {
|
|
144
|
+
AppError,
|
|
145
|
+
ForbiddenError,
|
|
146
|
+
NotFoundError,
|
|
147
|
+
PaymentError,
|
|
148
|
+
RateLimitError,
|
|
149
|
+
ServiceUnavailableError,
|
|
150
|
+
UnauthorizedError,
|
|
151
|
+
ValidationError,
|
|
152
|
+
createErrorHandler,
|
|
153
|
+
formatErrorResponse,
|
|
154
|
+
getErrorStatusCode,
|
|
155
|
+
isOperationalError
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @perkos/error-handling\n * Error handling utilities and classes for vendor services\n */\n\nimport { ZodError } from \"zod\";\n\n/**\n * Base application error class\n * Extends Error with HTTP status code and context\n */\nexport class AppError extends Error {\n public readonly statusCode: number;\n public readonly isOperational: boolean;\n public readonly context?: Record<string, any>;\n\n constructor(\n message: string,\n statusCode: number = 500,\n isOperational: boolean = true,\n context?: Record<string, any>\n ) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n\n this.name = this.constructor.name;\n this.statusCode = statusCode;\n this.isOperational = isOperational;\n this.context = context;\n\n Error.captureStackTrace(this);\n }\n\n toJSON() {\n return {\n error: this.message,\n statusCode: this.statusCode,\n context: this.context,\n };\n }\n}\n\n/**\n * Validation error class\n * For request validation failures with Zod integration\n */\nexport class ValidationError extends AppError {\n public readonly details?: any;\n\n constructor(message: string = \"Validation failed\", details?: any) {\n super(message, 400, true, { details });\n this.details = details;\n }\n\n /**\n * Create ValidationError from ZodError\n */\n static fromZodError(error: ZodError): ValidationError {\n const details = error.errors.map((e) => ({\n path: e.path.join(\".\"),\n message: e.message,\n code: e.code,\n }));\n return new ValidationError(\"Validation error\", details);\n }\n\n toJSON() {\n return {\n error: this.message,\n details: this.details,\n statusCode: this.statusCode,\n context: this.context,\n };\n }\n}\n\n/**\n * Payment error class\n * For x402 payment-related failures\n */\nexport class PaymentError extends AppError {\n public readonly reason?: string;\n public readonly transactionHash?: string;\n\n constructor(\n message: string,\n reason?: string,\n transactionHash?: string,\n context?: Record<string, any>\n ) {\n super(message, 402, true, context);\n this.reason = reason;\n this.transactionHash = transactionHash;\n }\n\n toJSON() {\n return {\n error: this.message,\n reason: this.reason,\n transactionHash: this.transactionHash,\n statusCode: this.statusCode,\n context: this.context,\n };\n }\n}\n\n/**\n * Not found error class\n */\nexport class NotFoundError extends AppError {\n constructor(message: string = \"Resource not found\", context?: Record<string, any>) {\n super(message, 404, true, context);\n }\n}\n\n/**\n * Unauthorized error class\n */\nexport class UnauthorizedError extends AppError {\n constructor(message: string = \"Unauthorized\", context?: Record<string, any>) {\n super(message, 401, true, context);\n }\n}\n\n/**\n * Forbidden error class\n */\nexport class ForbiddenError extends AppError {\n constructor(message: string = \"Forbidden\", context?: Record<string, any>) {\n super(message, 403, true, context);\n }\n}\n\n/**\n * Rate limit error class\n */\nexport class RateLimitError extends AppError {\n public readonly retryAfter?: number;\n\n constructor(\n message: string = \"Rate limit exceeded\",\n retryAfter?: number,\n context?: Record<string, any>\n ) {\n super(message, 429, true, context);\n this.retryAfter = retryAfter;\n }\n\n toJSON() {\n return {\n error: this.message,\n retryAfter: this.retryAfter,\n statusCode: this.statusCode,\n context: this.context,\n };\n }\n}\n\n/**\n * Service unavailable error class\n */\nexport class ServiceUnavailableError extends AppError {\n constructor(message: string = \"Service unavailable\", context?: Record<string, any>) {\n super(message, 503, true, context);\n }\n}\n\n/**\n * Check if error is operational (expected) or programming error\n */\nexport function isOperationalError(error: Error): boolean {\n if (error instanceof AppError) {\n return error.isOperational;\n }\n return false;\n}\n\n/**\n * Error response formatter for API responses\n */\nexport interface ErrorResponse {\n error: string;\n message?: string;\n details?: any;\n statusCode: number;\n}\n\n/**\n * Format error for API response\n */\nexport function formatErrorResponse(error: unknown): ErrorResponse {\n if (error instanceof ZodError) {\n const validationError = ValidationError.fromZodError(error);\n return validationError.toJSON() as ErrorResponse;\n }\n\n if (error instanceof AppError) {\n return error.toJSON() as ErrorResponse;\n }\n\n if (error instanceof Error) {\n return {\n error: error.message,\n statusCode: 500,\n };\n }\n\n return {\n error: \"Unknown error\",\n statusCode: 500,\n };\n}\n\n/**\n * Get HTTP status code from error\n */\nexport function getErrorStatusCode(error: unknown): number {\n if (error instanceof AppError) {\n return error.statusCode;\n }\n if (error instanceof ZodError) {\n return 400;\n }\n return 500;\n}\n\n/**\n * Create error handler middleware (framework-agnostic)\n */\nexport function createErrorHandler(options?: {\n logger?: (error: Error, context?: Record<string, any>) => void;\n includeStack?: boolean;\n}) {\n return (error: unknown) => {\n const response = formatErrorResponse(error);\n const statusCode = getErrorStatusCode(error);\n\n if (options?.logger && error instanceof Error) {\n options.logger(error, { statusCode });\n }\n\n if (options?.includeStack && error instanceof Error) {\n (response as any).stack = error.stack;\n }\n\n return { response, statusCode };\n };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@perkos/util-errors",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Error handling utilities and classes for vendor services",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"lint": "tsc --noEmit",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"clean": "rm -rf dist",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"error",
|
|
28
|
+
"handling",
|
|
29
|
+
"validation",
|
|
30
|
+
"zod",
|
|
31
|
+
"api",
|
|
32
|
+
"perkos"
|
|
33
|
+
],
|
|
34
|
+
"author": "PerkOS",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/PerkOS-xyz/pkg-util-errors.git"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"zod": "^3.22.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^20.10.0",
|
|
45
|
+
"tsup": "^8.0.1",
|
|
46
|
+
"typescript": "^5.3.3",
|
|
47
|
+
"vitest": "^1.2.0"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18.0.0"
|
|
51
|
+
}
|
|
52
|
+
}
|