@devua-lab/error-serialization 1.0.0 → 1.0.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 +123 -84
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @devua-lab/error-serialization
|
|
2
2
|
|
|
3
3
|
A lightweight, highly extensible TypeScript library for standardized error serialization. It provides a unified pipeline to transform any error—from Zod validation issues and Axios HTTP failures to native JavaScript errors and raw strings—into a consistent, strictly typed response format.
|
|
4
4
|
|
|
@@ -7,16 +7,18 @@ A lightweight, highly extensible TypeScript library for standardized error seria
|
|
|
7
7
|
## 📑 Table of Contents
|
|
8
8
|
|
|
9
9
|
1. [Features](#features)
|
|
10
|
-
2. [
|
|
11
|
-
3. [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
2. [Installation](#installation)
|
|
11
|
+
3. [Quick Start](#quick-start)
|
|
12
|
+
4. [Usage Guide](#usage-guide)
|
|
13
|
+
- [1. Setup & Registration](#1-setup--registration)
|
|
14
|
+
- [2. Processing Errors](#2-processing-errors)
|
|
15
|
+
- [3. Global Subscriptions](#3-global-subscriptions)
|
|
16
|
+
5. [Standard Response Format](#standard-response-format)
|
|
17
|
+
6. [Standard Plugins](#standard-plugins)
|
|
18
|
+
- [ZodErrorPlugin](#zoderrorplugin)
|
|
19
|
+
- [AxiosErrorPlugin](#axioserrorplugin)
|
|
20
|
+
- [StandardErrorPlugin](#standarderrorplugin)
|
|
21
|
+
7. [Priority System](#priority-system)
|
|
20
22
|
|
|
21
23
|
---
|
|
22
24
|
|
|
@@ -25,110 +27,147 @@ A lightweight, highly extensible TypeScript library for standardized error seria
|
|
|
25
27
|
- **🎯 Universal Standardization**: Regardless of the error source, the output always follows the same predictable interface.
|
|
26
28
|
- **🏗️ Structured Validation Mapping**: Advanced transformation of Zod issues into flat keys or deep object hierarchies.
|
|
27
29
|
- **🌐 Generic API Extraction**: Smart parsing of backend error messages and codes from HTTP responses.
|
|
28
|
-
- **🚀 Priority-Based Execution**: Automatically selects the most appropriate handler
|
|
29
|
-
- **🔔 Real-time Subscriptions**:
|
|
30
|
-
- **🛡️ Preservation of Context**:
|
|
31
|
-
- **🔌 Plugin-Driven**: Easily register new handlers for custom application-specific error classes.
|
|
30
|
+
- **🚀 Priority-Based Execution**: Automatically selects the most appropriate handler.
|
|
31
|
+
- **🔔 Real-time Subscriptions**: Simple callback system for global error monitoring.
|
|
32
|
+
- **🛡️ Preservation of Context**: Access low-level details (like Axios request configs) via the preserved original error.
|
|
32
33
|
|
|
33
34
|
---
|
|
34
35
|
|
|
35
|
-
##
|
|
36
|
+
## 📦 Installation
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
{
|
|
41
|
-
metadata: {
|
|
42
|
-
plugin: string; // The plugin that successfully handled the error
|
|
43
|
-
priority: number; // Priority level of the handling plugin
|
|
44
|
-
},
|
|
45
|
-
error: unknown; // The ORIGINAL error object (preserved for logging/debugging)
|
|
46
|
-
global?: string; // A primary human-readable error message
|
|
47
|
-
code?: string[]; // Standardized error identifiers (e.g., ["102", "CONFLICT"])
|
|
48
|
-
status?: number; // Numeric status code (e.g., 422, 404, 500, or 0 for network issues)
|
|
49
|
-
validation?: { // Detailed field-level errors (primarily for Zod)
|
|
50
|
-
[key: string]: any;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
38
|
+
```bash
|
|
39
|
+
npm install @devua-lab/error-serialization
|
|
53
40
|
```
|
|
54
41
|
|
|
55
|
-
|
|
42
|
+
### Peer Dependencies
|
|
43
|
+
This library requires `axios` and `zod` to be installed in your project as peer dependencies:
|
|
56
44
|
|
|
57
|
-
|
|
45
|
+
```bash
|
|
46
|
+
npm install axios zod
|
|
47
|
+
```
|
|
58
48
|
|
|
59
|
-
|
|
60
|
-
Designed for `ZodError` instances. It translates complex validation issues into formats suitable for frontend state.
|
|
61
|
-
- **Status Code**: Returns `422`.
|
|
62
|
-
- **Default Code**: `["102"]`.
|
|
63
|
-
- **Flexible Pathing**: Correctly handles array indices (e.g., `list.0.name`) and nested properties.
|
|
64
|
-
- **Customizable**: Use `mapIssue` to dynamically rewrite messages or inject specific codes based on validation parameters.
|
|
49
|
+
---
|
|
65
50
|
|
|
66
|
-
|
|
67
|
-
A generic handler for `AxiosError`. It is designed to work with virtually any backend error structure.
|
|
68
|
-
- **Message Parsing**: Scans the response body for `message` or `error.message`.
|
|
69
|
-
- **Code Parsing**: Extracts `code` or `errorCode` from response data.
|
|
70
|
-
- **Network Awareness**: Provides fallback status `0` and generic codes (e.g., `HTTP_0`) when a server response is absent (Network Error).
|
|
51
|
+
## 🚀 Quick Start
|
|
71
52
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
53
|
+
```typescript
|
|
54
|
+
import { ErrorSerializer, ZodErrorPlugin, AxiosErrorPlugin } from '@devua-lab/error-serialization';
|
|
55
|
+
|
|
56
|
+
// 1. Initialize
|
|
57
|
+
const serializer = new ErrorSerializer();
|
|
58
|
+
|
|
59
|
+
// 2. Register plugins
|
|
60
|
+
serializer
|
|
61
|
+
.register(new AxiosErrorPlugin())
|
|
62
|
+
.register(new ZodErrorPlugin({ structure: 'nested' }));
|
|
63
|
+
|
|
64
|
+
// 3. Use in your application
|
|
65
|
+
try {
|
|
66
|
+
await api.post('/login', data);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
const result = serializer.process(error);
|
|
69
|
+
console.log(result.global); // "Invalid credentials"
|
|
70
|
+
console.log(result.status); // 401
|
|
71
|
+
}
|
|
72
|
+
```
|
|
76
73
|
|
|
77
74
|
---
|
|
78
75
|
|
|
79
|
-
##
|
|
76
|
+
## 🛠 Usage Guide
|
|
80
77
|
|
|
81
|
-
###
|
|
82
|
-
|
|
78
|
+
### 1. Setup & Registration
|
|
79
|
+
Create a central error utility in your app to reuse the serializer instance. Register plugins in any order; the library will sort them by internal priority.
|
|
83
80
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
81
|
+
```typescript
|
|
82
|
+
// error-utility.ts
|
|
83
|
+
import {
|
|
84
|
+
ErrorSerializer,
|
|
85
|
+
ZodErrorPlugin,
|
|
86
|
+
AxiosErrorPlugin,
|
|
87
|
+
StandardErrorPlugin
|
|
88
|
+
} from '@devua-lab/error-serialization';
|
|
89
|
+
|
|
90
|
+
export const errorSerializer = new ErrorSerializer();
|
|
91
|
+
|
|
92
|
+
errorSerializer
|
|
93
|
+
.register(new StandardErrorPlugin())
|
|
94
|
+
.register(new AxiosErrorPlugin())
|
|
95
|
+
.register(new ZodErrorPlugin({
|
|
96
|
+
structure: 'flat',
|
|
97
|
+
messageFormat: 'string'
|
|
98
|
+
}));
|
|
99
|
+
```
|
|
90
100
|
|
|
91
|
-
###
|
|
92
|
-
|
|
101
|
+
### 2. Processing Errors
|
|
102
|
+
Simply wrap your logic in a `try/catch` block and pass the caught error to the `process` method.
|
|
93
103
|
|
|
94
104
|
```typescript
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
import { errorSerializer } from './error-utility';
|
|
106
|
+
|
|
107
|
+
async function handleSubmit(formData: any) {
|
|
108
|
+
try {
|
|
109
|
+
const validated = schema.parse(formData);
|
|
110
|
+
await userService.create(validated);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
const error = errorSerializer.process(err);
|
|
113
|
+
|
|
114
|
+
if (error.status === 422) {
|
|
115
|
+
// Handle validation errors in UI
|
|
116
|
+
setFormErrors(error.validation);
|
|
117
|
+
} else {
|
|
118
|
+
// Show global notification
|
|
119
|
+
toast.error(error.global || "Something went wrong");
|
|
120
|
+
}
|
|
100
121
|
}
|
|
101
|
-
|
|
102
|
-
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 3. Global Subscriptions
|
|
126
|
+
Use subscriptions to automate logging or reporting without cluttering your business logic.
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
errorSerializer.subscribe((context) => {
|
|
130
|
+
// Report critical errors to Sentry
|
|
103
131
|
if (context.status && context.status >= 500) {
|
|
104
|
-
|
|
132
|
+
Sentry.captureException(context.error);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Analytics for specific error codes
|
|
136
|
+
if (context.code?.includes('AUTH_EXPIRED')) {
|
|
137
|
+
analytics.track('Session Timeout');
|
|
105
138
|
}
|
|
106
139
|
});
|
|
107
140
|
```
|
|
108
141
|
|
|
109
142
|
---
|
|
110
143
|
|
|
111
|
-
##
|
|
144
|
+
## 🏗 Standard Response Format
|
|
145
|
+
|
|
146
|
+
The `process` method always returns an `AppErrorResponse` object:
|
|
112
147
|
|
|
113
|
-
### Custom Zod Mapping
|
|
114
148
|
```typescript
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
149
|
+
{
|
|
150
|
+
metadata: {
|
|
151
|
+
plugin: string; // Plugin name (e.g., "ZodErrorPlugin" or "ErrorSerializer" for fallbacks)
|
|
152
|
+
priority: number; // Level (2: Zod, 1: Axios, 0: Standard, -1: Fallback)
|
|
153
|
+
},
|
|
154
|
+
error: unknown; // The ORIGINAL error object
|
|
155
|
+
global?: string; // Main human-readable message
|
|
156
|
+
code?: string[]; // Array of error codes (e.g., ["102", "CONFLICT"])
|
|
157
|
+
status?: number; // Numeric status code (e.g., 422, 500, or 0)
|
|
158
|
+
validation?: { // Object with field-level errors
|
|
159
|
+
[key: string]: any;
|
|
120
160
|
}
|
|
121
|
-
}
|
|
161
|
+
}
|
|
122
162
|
```
|
|
123
163
|
|
|
124
164
|
---
|
|
125
165
|
|
|
126
|
-
##
|
|
166
|
+
## ⚙️ Priority System
|
|
127
167
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
- **Subscription Integrity**: Confirmation that simplified callbacks receive the full `AppErrorResponse`.
|
|
168
|
+
| Plugin | Priority | Matching Criteria |
|
|
169
|
+
| :--- | :--- | :--- |
|
|
170
|
+
| **ZodErrorPlugin** | 2 | `instanceof ZodError` |
|
|
171
|
+
| **AxiosErrorPlugin** | 1 | `axios.isAxiosError(error)` |
|
|
172
|
+
| **StandardErrorPlugin** | 0 | `instanceof Error` |
|
|
173
|
+
| **ErrorSerializer** | -1 | Fallback for raw strings, numbers, or null |
|