@onlineapps/conn-infra-error-handler 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/API.md +637 -0
- package/package.json +34 -0
- package/src/index.js +822 -0
- package/test/component/error-handling-flow.test.js +336 -0
- package/test/unit/ErrorHandlerConnector.test.js +294 -0
package/API.md
ADDED
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
<a name="module_@onlineapps/conn-infra-error-handler"></a>
|
|
2
|
+
|
|
3
|
+
## @onlineapps/conn-infra-error-handler
|
|
4
|
+
Unified error handling connector providing retry strategies, circuit breaker pattern,
|
|
5
|
+
and compensation mechanisms for OA Drive microservices.
|
|
6
|
+
|
|
7
|
+
**See**: [GitHub Repository](https://github.com/onlineapps/oa-drive/tree/main/shared/connector/conn-infra-error-handler)
|
|
8
|
+
**Since**: 1.0.0
|
|
9
|
+
**Author**: OA Drive Team
|
|
10
|
+
**License**: MIT
|
|
11
|
+
|
|
12
|
+
* [@onlineapps/conn-infra-error-handler](#module_@onlineapps/conn-infra-error-handler)
|
|
13
|
+
* _static_
|
|
14
|
+
* [.ErrorTypes](#module_@onlineapps/conn-infra-error-handler.ErrorTypes) : <code>enum</code>
|
|
15
|
+
* [.ErrorCodes](#module_@onlineapps/conn-infra-error-handler.ErrorCodes) : <code>enum</code>
|
|
16
|
+
* [.VERSION](#module_@onlineapps/conn-infra-error-handler.VERSION) : <code>string</code>
|
|
17
|
+
* _inner_
|
|
18
|
+
* [~ErrorHandlerConnector](#module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector)
|
|
19
|
+
* [new ErrorHandlerConnector()](#new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new)
|
|
20
|
+
* [new ErrorHandlerConnector([config])](#new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new)
|
|
21
|
+
* [.getCircuitBreaker(name, fn, options)](#module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector+getCircuitBreaker) ⇒ <code>CircuitBreaker</code>
|
|
22
|
+
* [~ErrorHandlerConnector](#module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector)
|
|
23
|
+
* [new ErrorHandlerConnector()](#new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new)
|
|
24
|
+
* [new ErrorHandlerConnector([config])](#new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new)
|
|
25
|
+
* [.getCircuitBreaker(name, fn, options)](#module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector+getCircuitBreaker) ⇒ <code>CircuitBreaker</code>
|
|
26
|
+
* [~classifyError(error)](#module_@onlineapps/conn-infra-error-handler..classifyError) ⇒ <code>string</code>
|
|
27
|
+
* [~shouldRetry(error, [attempts])](#module_@onlineapps/conn-infra-error-handler..shouldRetry) ⇒ <code>boolean</code>
|
|
28
|
+
* [~calculateBackoff(attempts)](#module_@onlineapps/conn-infra-error-handler..calculateBackoff) ⇒ <code>number</code>
|
|
29
|
+
* [~executeWithRetry(fn, [options])](#module_@onlineapps/conn-infra-error-handler..executeWithRetry) ⇒ <code>Promise.<\*></code>
|
|
30
|
+
* [~executeWithCircuitBreaker(name, fn, [options])](#module_@onlineapps/conn-infra-error-handler..executeWithCircuitBreaker) ⇒ <code>Promise.<\*></code>
|
|
31
|
+
* [~registerCompensation(operation, handler)](#module_@onlineapps/conn-infra-error-handler..registerCompensation) ⇒ <code>void</code>
|
|
32
|
+
* [~executeCompensation(operation, context)](#module_@onlineapps/conn-infra-error-handler..executeCompensation) ⇒ <code>Promise.<\*></code>
|
|
33
|
+
* [~routeToDLQ(mqClient, message, error)](#module_@onlineapps/conn-infra-error-handler..routeToDLQ) ⇒ <code>Promise.<void></code>
|
|
34
|
+
* [~createErrorResponse(error, [context])](#module_@onlineapps/conn-infra-error-handler..createErrorResponse) ⇒ <code>ErrorResponse</code>
|
|
35
|
+
* [~wrap(fn, [options])](#module_@onlineapps/conn-infra-error-handler..wrap) ⇒ <code>function</code>
|
|
36
|
+
* [~handleWorkflowError(workflow, error, failedStep)](#module_@onlineapps/conn-infra-error-handler..handleWorkflowError) ⇒ <code>Promise.<WorkflowErrorResult></code>
|
|
37
|
+
* [~getStats()](#module_@onlineapps/conn-infra-error-handler..getStats) ⇒ <code>ErrorStats</code>
|
|
38
|
+
* [~resetStats()](#module_@onlineapps/conn-infra-error-handler..resetStats) ⇒ <code>void</code>
|
|
39
|
+
* [~create(config)](#module_@onlineapps/conn-infra-error-handler..create) ⇒ <code>ErrorHandlerConnector</code>
|
|
40
|
+
* [~ErrorResponse](#module_@onlineapps/conn-infra-error-handler..ErrorResponse) : <code>Object</code>
|
|
41
|
+
* [~WorkflowErrorResult](#module_@onlineapps/conn-infra-error-handler..WorkflowErrorResult) : <code>Object</code>
|
|
42
|
+
* [~ErrorStats](#module_@onlineapps/conn-infra-error-handler..ErrorStats) : <code>Object</code>
|
|
43
|
+
|
|
44
|
+
<a name="module_@onlineapps/conn-infra-error-handler.ErrorTypes"></a>
|
|
45
|
+
|
|
46
|
+
### @onlineapps/conn-infra-error-handler.ErrorTypes : <code>enum</code>
|
|
47
|
+
Error type enumeration
|
|
48
|
+
|
|
49
|
+
**Kind**: static enum of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
50
|
+
<a name="module_@onlineapps/conn-infra-error-handler.ErrorCodes"></a>
|
|
51
|
+
|
|
52
|
+
### @onlineapps/conn-infra-error-handler.ErrorCodes : <code>enum</code>
|
|
53
|
+
Standard error code mappings
|
|
54
|
+
|
|
55
|
+
**Kind**: static enum of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
56
|
+
<a name="module_@onlineapps/conn-infra-error-handler.VERSION"></a>
|
|
57
|
+
|
|
58
|
+
### @onlineapps/conn-infra-error-handler.VERSION : <code>string</code>
|
|
59
|
+
Current version
|
|
60
|
+
|
|
61
|
+
**Kind**: static constant of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
62
|
+
<a name="module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector"></a>
|
|
63
|
+
|
|
64
|
+
### @onlineapps/conn-infra-error-handler~ErrorHandlerConnector
|
|
65
|
+
**Kind**: inner class of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
66
|
+
|
|
67
|
+
* [~ErrorHandlerConnector](#module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector)
|
|
68
|
+
* [new ErrorHandlerConnector()](#new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new)
|
|
69
|
+
* [new ErrorHandlerConnector([config])](#new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new)
|
|
70
|
+
* [.getCircuitBreaker(name, fn, options)](#module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector+getCircuitBreaker) ⇒ <code>CircuitBreaker</code>
|
|
71
|
+
|
|
72
|
+
<a name="new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new"></a>
|
|
73
|
+
|
|
74
|
+
#### new ErrorHandlerConnector()
|
|
75
|
+
Error handling connector with retry, circuit breaker, and compensation
|
|
76
|
+
|
|
77
|
+
**Example** *(Basic Usage)*
|
|
78
|
+
```js
|
|
79
|
+
const errorHandler = new ErrorHandlerConnector({
|
|
80
|
+
maxRetries: 3,
|
|
81
|
+
retryDelay: 1000
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const result = await errorHandler.executeWithRetry(async () => {
|
|
85
|
+
return await riskyOperation();
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
**Example** *(With Circuit Breaker)*
|
|
89
|
+
```js
|
|
90
|
+
const errorHandler = new ErrorHandlerConnector({
|
|
91
|
+
circuitBreakerEnabled: true,
|
|
92
|
+
errorThreshold: 50
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
await errorHandler.executeWithCircuitBreaker('api-call', async () => {
|
|
96
|
+
return await apiClient.call();
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
<a name="new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new"></a>
|
|
100
|
+
|
|
101
|
+
#### new ErrorHandlerConnector([config])
|
|
102
|
+
Creates a new ErrorHandlerConnector instance
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
| Param | Type | Default | Description |
|
|
106
|
+
| --- | --- | --- | --- |
|
|
107
|
+
| [config] | <code>Object</code> | <code>{}</code> | Configuration options |
|
|
108
|
+
| [config.maxRetries] | <code>number</code> | <code>3</code> | Maximum retry attempts |
|
|
109
|
+
| [config.retryDelay] | <code>number</code> | <code>1000</code> | Initial retry delay in ms |
|
|
110
|
+
| [config.retryMultiplier] | <code>number</code> | <code>2</code> | Backoff multiplier |
|
|
111
|
+
| [config.maxRetryDelay] | <code>number</code> | <code>30000</code> | Maximum retry delay |
|
|
112
|
+
| [config.circuitBreakerEnabled] | <code>boolean</code> | <code>true</code> | Enable circuit breaker |
|
|
113
|
+
| [config.circuitTimeout] | <code>number</code> | <code>10000</code> | Circuit breaker timeout |
|
|
114
|
+
| [config.errorThreshold] | <code>number</code> | <code>50</code> | Error threshold percentage |
|
|
115
|
+
| [config.resetTimeout] | <code>number</code> | <code>30000</code> | Circuit reset timeout |
|
|
116
|
+
| [config.compensationEnabled] | <code>boolean</code> | <code>true</code> | Enable compensation |
|
|
117
|
+
| [config.circuitBreakerOptions] | <code>Object</code> | | Additional circuit breaker options |
|
|
118
|
+
|
|
119
|
+
**Example** *(Full Configuration)*
|
|
120
|
+
```js
|
|
121
|
+
const errorHandler = new ErrorHandlerConnector({
|
|
122
|
+
maxRetries: 5,
|
|
123
|
+
retryDelay: 500,
|
|
124
|
+
retryMultiplier: 1.5,
|
|
125
|
+
maxRetryDelay: 20000,
|
|
126
|
+
circuitBreakerEnabled: true,
|
|
127
|
+
errorThreshold: 60,
|
|
128
|
+
compensationEnabled: true
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
<a name="module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector+getCircuitBreaker"></a>
|
|
132
|
+
|
|
133
|
+
#### errorHandlerConnector.getCircuitBreaker(name, fn, options) ⇒ <code>CircuitBreaker</code>
|
|
134
|
+
Get or create circuit breaker for operation
|
|
135
|
+
|
|
136
|
+
**Kind**: instance method of [<code>ErrorHandlerConnector</code>](#module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector)
|
|
137
|
+
**Returns**: <code>CircuitBreaker</code> - Circuit breaker instance
|
|
138
|
+
|
|
139
|
+
| Param | Type | Description |
|
|
140
|
+
| --- | --- | --- |
|
|
141
|
+
| name | <code>string</code> | Operation name |
|
|
142
|
+
| fn | <code>function</code> | Function to protect |
|
|
143
|
+
| options | <code>object</code> | Circuit breaker options |
|
|
144
|
+
|
|
145
|
+
<a name="module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector"></a>
|
|
146
|
+
|
|
147
|
+
### @onlineapps/conn-infra-error-handler~ErrorHandlerConnector
|
|
148
|
+
**Kind**: inner class of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
149
|
+
|
|
150
|
+
* [~ErrorHandlerConnector](#module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector)
|
|
151
|
+
* [new ErrorHandlerConnector()](#new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new)
|
|
152
|
+
* [new ErrorHandlerConnector([config])](#new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new)
|
|
153
|
+
* [.getCircuitBreaker(name, fn, options)](#module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector+getCircuitBreaker) ⇒ <code>CircuitBreaker</code>
|
|
154
|
+
|
|
155
|
+
<a name="new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new"></a>
|
|
156
|
+
|
|
157
|
+
#### new ErrorHandlerConnector()
|
|
158
|
+
Error handling connector with retry, circuit breaker, and compensation
|
|
159
|
+
|
|
160
|
+
**Example** *(Basic Usage)*
|
|
161
|
+
```js
|
|
162
|
+
const errorHandler = new ErrorHandlerConnector({
|
|
163
|
+
maxRetries: 3,
|
|
164
|
+
retryDelay: 1000
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const result = await errorHandler.executeWithRetry(async () => {
|
|
168
|
+
return await riskyOperation();
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
**Example** *(With Circuit Breaker)*
|
|
172
|
+
```js
|
|
173
|
+
const errorHandler = new ErrorHandlerConnector({
|
|
174
|
+
circuitBreakerEnabled: true,
|
|
175
|
+
errorThreshold: 50
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
await errorHandler.executeWithCircuitBreaker('api-call', async () => {
|
|
179
|
+
return await apiClient.call();
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
<a name="new_module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector_new"></a>
|
|
183
|
+
|
|
184
|
+
#### new ErrorHandlerConnector([config])
|
|
185
|
+
Creates a new ErrorHandlerConnector instance
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
| Param | Type | Default | Description |
|
|
189
|
+
| --- | --- | --- | --- |
|
|
190
|
+
| [config] | <code>Object</code> | <code>{}</code> | Configuration options |
|
|
191
|
+
| [config.maxRetries] | <code>number</code> | <code>3</code> | Maximum retry attempts |
|
|
192
|
+
| [config.retryDelay] | <code>number</code> | <code>1000</code> | Initial retry delay in ms |
|
|
193
|
+
| [config.retryMultiplier] | <code>number</code> | <code>2</code> | Backoff multiplier |
|
|
194
|
+
| [config.maxRetryDelay] | <code>number</code> | <code>30000</code> | Maximum retry delay |
|
|
195
|
+
| [config.circuitBreakerEnabled] | <code>boolean</code> | <code>true</code> | Enable circuit breaker |
|
|
196
|
+
| [config.circuitTimeout] | <code>number</code> | <code>10000</code> | Circuit breaker timeout |
|
|
197
|
+
| [config.errorThreshold] | <code>number</code> | <code>50</code> | Error threshold percentage |
|
|
198
|
+
| [config.resetTimeout] | <code>number</code> | <code>30000</code> | Circuit reset timeout |
|
|
199
|
+
| [config.compensationEnabled] | <code>boolean</code> | <code>true</code> | Enable compensation |
|
|
200
|
+
| [config.circuitBreakerOptions] | <code>Object</code> | | Additional circuit breaker options |
|
|
201
|
+
|
|
202
|
+
**Example** *(Full Configuration)*
|
|
203
|
+
```js
|
|
204
|
+
const errorHandler = new ErrorHandlerConnector({
|
|
205
|
+
maxRetries: 5,
|
|
206
|
+
retryDelay: 500,
|
|
207
|
+
retryMultiplier: 1.5,
|
|
208
|
+
maxRetryDelay: 20000,
|
|
209
|
+
circuitBreakerEnabled: true,
|
|
210
|
+
errorThreshold: 60,
|
|
211
|
+
compensationEnabled: true
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
<a name="module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector+getCircuitBreaker"></a>
|
|
215
|
+
|
|
216
|
+
#### errorHandlerConnector.getCircuitBreaker(name, fn, options) ⇒ <code>CircuitBreaker</code>
|
|
217
|
+
Get or create circuit breaker for operation
|
|
218
|
+
|
|
219
|
+
**Kind**: instance method of [<code>ErrorHandlerConnector</code>](#module_@onlineapps/conn-infra-error-handler..ErrorHandlerConnector)
|
|
220
|
+
**Returns**: <code>CircuitBreaker</code> - Circuit breaker instance
|
|
221
|
+
|
|
222
|
+
| Param | Type | Description |
|
|
223
|
+
| --- | --- | --- |
|
|
224
|
+
| name | <code>string</code> | Operation name |
|
|
225
|
+
| fn | <code>function</code> | Function to protect |
|
|
226
|
+
| options | <code>object</code> | Circuit breaker options |
|
|
227
|
+
|
|
228
|
+
<a name="module_@onlineapps/conn-infra-error-handler..classifyError"></a>
|
|
229
|
+
|
|
230
|
+
### @onlineapps/conn-infra-error-handler~classifyError(error) ⇒ <code>string</code>
|
|
231
|
+
Classify error into type for appropriate handling
|
|
232
|
+
|
|
233
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
234
|
+
**Returns**: <code>string</code> - Error type from ErrorTypes enum
|
|
235
|
+
|
|
236
|
+
| Param | Type | Description |
|
|
237
|
+
| --- | --- | --- |
|
|
238
|
+
| error | <code>Error</code> | Error to classify |
|
|
239
|
+
| [error.code] | <code>string</code> | Error code (e.g., ECONNREFUSED) |
|
|
240
|
+
| [error.statusCode] | <code>number</code> | HTTP status code |
|
|
241
|
+
| [error.type] | <code>string</code> | Explicit error type |
|
|
242
|
+
|
|
243
|
+
**Example** *(Network Error)*
|
|
244
|
+
```js
|
|
245
|
+
const type = errorHandler.classifyError(new Error('ECONNREFUSED'));
|
|
246
|
+
// Returns: 'TRANSIENT'
|
|
247
|
+
```
|
|
248
|
+
**Example** *(HTTP Error)*
|
|
249
|
+
```js
|
|
250
|
+
const error = new Error('Not Found');
|
|
251
|
+
error.statusCode = 404;
|
|
252
|
+
const type = errorHandler.classifyError(error);
|
|
253
|
+
// Returns: 'BUSINESS'
|
|
254
|
+
```
|
|
255
|
+
**Example** *(Timeout Error)*
|
|
256
|
+
```js
|
|
257
|
+
const type = errorHandler.classifyError(new Error('Operation timeout'));
|
|
258
|
+
// Returns: 'TIMEOUT'
|
|
259
|
+
```
|
|
260
|
+
<a name="module_@onlineapps/conn-infra-error-handler..shouldRetry"></a>
|
|
261
|
+
|
|
262
|
+
### @onlineapps/conn-infra-error-handler~shouldRetry(error, [attempts]) ⇒ <code>boolean</code>
|
|
263
|
+
Determine if error should be retried
|
|
264
|
+
|
|
265
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
266
|
+
**Returns**: <code>boolean</code> - True if should retry
|
|
267
|
+
|
|
268
|
+
| Param | Type | Default | Description |
|
|
269
|
+
| --- | --- | --- | --- |
|
|
270
|
+
| error | <code>Error</code> | | Error to check |
|
|
271
|
+
| [attempts] | <code>number</code> | <code>0</code> | Current attempt count |
|
|
272
|
+
|
|
273
|
+
**Example**
|
|
274
|
+
```js
|
|
275
|
+
const error = new Error('Connection refused');
|
|
276
|
+
if (errorHandler.shouldRetry(error, 1)) {
|
|
277
|
+
// Retry the operation
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
<a name="module_@onlineapps/conn-infra-error-handler..calculateBackoff"></a>
|
|
281
|
+
|
|
282
|
+
### @onlineapps/conn-infra-error-handler~calculateBackoff(attempts) ⇒ <code>number</code>
|
|
283
|
+
Calculate exponential backoff delay
|
|
284
|
+
|
|
285
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
286
|
+
**Returns**: <code>number</code> - Delay in milliseconds
|
|
287
|
+
|
|
288
|
+
| Param | Type | Description |
|
|
289
|
+
| --- | --- | --- |
|
|
290
|
+
| attempts | <code>number</code> | Current attempt number (1-based) |
|
|
291
|
+
|
|
292
|
+
**Example**
|
|
293
|
+
```js
|
|
294
|
+
const delay = errorHandler.calculateBackoff(3);
|
|
295
|
+
// With default config: 1000 * 2^2 = 4000ms
|
|
296
|
+
```
|
|
297
|
+
<a name="module_@onlineapps/conn-infra-error-handler..executeWithRetry"></a>
|
|
298
|
+
|
|
299
|
+
### @onlineapps/conn-infra-error-handler~executeWithRetry(fn, [options]) ⇒ <code>Promise.<\*></code>
|
|
300
|
+
Execute function with automatic retry on failure
|
|
301
|
+
|
|
302
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
303
|
+
**Returns**: <code>Promise.<\*></code> - Function result
|
|
304
|
+
**Throws**:
|
|
305
|
+
|
|
306
|
+
- <code>Error</code> Last error if all retries fail
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
| Param | Type | Default | Description |
|
|
310
|
+
| --- | --- | --- | --- |
|
|
311
|
+
| fn | <code>function</code> | | Async function to execute |
|
|
312
|
+
| [options] | <code>Object</code> | <code>{}</code> | Retry options |
|
|
313
|
+
| [options.maxRetries] | <code>number</code> | | Override max retries |
|
|
314
|
+
| [options.retryOn] | <code>Array.<string></code> | <code>[]</code> | Additional error codes to retry |
|
|
315
|
+
| [options.onRetry] | <code>function</code> | | Callback on retry (error, attempt, delay) |
|
|
316
|
+
|
|
317
|
+
**Example** *(Simple Retry)*
|
|
318
|
+
```js
|
|
319
|
+
const result = await errorHandler.executeWithRetry(async () => {
|
|
320
|
+
return await apiClient.fetchData();
|
|
321
|
+
});
|
|
322
|
+
```
|
|
323
|
+
**Example** *(With Options)*
|
|
324
|
+
```js
|
|
325
|
+
const result = await errorHandler.executeWithRetry(
|
|
326
|
+
async () => await riskyOperation(),
|
|
327
|
+
{
|
|
328
|
+
maxRetries: 5,
|
|
329
|
+
retryOn: ['CUSTOM_ERROR'],
|
|
330
|
+
onRetry: (error, attempt, delay) => {
|
|
331
|
+
console.log(`Retry ${attempt} after ${delay}ms`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
);
|
|
335
|
+
```
|
|
336
|
+
**Example** *(Database Operation)*
|
|
337
|
+
```js
|
|
338
|
+
const data = await errorHandler.executeWithRetry(async () => {
|
|
339
|
+
const conn = await db.connect();
|
|
340
|
+
try {
|
|
341
|
+
return await conn.query('SELECT * FROM users');
|
|
342
|
+
} finally {
|
|
343
|
+
conn.close();
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
```
|
|
347
|
+
<a name="module_@onlineapps/conn-infra-error-handler..executeWithCircuitBreaker"></a>
|
|
348
|
+
|
|
349
|
+
### @onlineapps/conn-infra-error-handler~executeWithCircuitBreaker(name, fn, [options]) ⇒ <code>Promise.<\*></code>
|
|
350
|
+
Execute function with circuit breaker protection
|
|
351
|
+
|
|
352
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
353
|
+
**Returns**: <code>Promise.<\*></code> - Function result
|
|
354
|
+
**Throws**:
|
|
355
|
+
|
|
356
|
+
- <code>Error</code> If circuit is open or operation fails
|
|
357
|
+
|
|
358
|
+
**Emits**: <code>CircuitBreaker#event:open - When circuit opens</code>, <code>CircuitBreaker#event:halfOpen - When circuit enters half-open state</code>
|
|
359
|
+
|
|
360
|
+
| Param | Type | Default | Description |
|
|
361
|
+
| --- | --- | --- | --- |
|
|
362
|
+
| name | <code>string</code> | | Operation name for circuit breaker |
|
|
363
|
+
| fn | <code>function</code> | | Async function to execute |
|
|
364
|
+
| [options] | <code>Object</code> | <code>{}</code> | Circuit breaker options |
|
|
365
|
+
| [options.timeout] | <code>number</code> | | Operation timeout |
|
|
366
|
+
| [options.errorThresholdPercentage] | <code>number</code> | | Error threshold |
|
|
367
|
+
|
|
368
|
+
**Example** *(API Call Protection)*
|
|
369
|
+
```js
|
|
370
|
+
try {
|
|
371
|
+
const data = await errorHandler.executeWithCircuitBreaker(
|
|
372
|
+
'user-api',
|
|
373
|
+
async () => await userAPI.getUser(id)
|
|
374
|
+
);
|
|
375
|
+
} catch (error) {
|
|
376
|
+
if (error.message.includes('circuit is open')) {
|
|
377
|
+
// Service is down, use fallback
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
**Example** *(With Custom Options)*
|
|
382
|
+
```js
|
|
383
|
+
const result = await errorHandler.executeWithCircuitBreaker(
|
|
384
|
+
'payment-gateway',
|
|
385
|
+
async () => await processPayment(order),
|
|
386
|
+
{
|
|
387
|
+
timeout: 5000,
|
|
388
|
+
errorThresholdPercentage: 30
|
|
389
|
+
}
|
|
390
|
+
);
|
|
391
|
+
```
|
|
392
|
+
<a name="module_@onlineapps/conn-infra-error-handler..registerCompensation"></a>
|
|
393
|
+
|
|
394
|
+
### @onlineapps/conn-infra-error-handler~registerCompensation(operation, handler) ⇒ <code>void</code>
|
|
395
|
+
Register compensation handler for an operation
|
|
396
|
+
|
|
397
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
398
|
+
|
|
399
|
+
| Param | Type | Description |
|
|
400
|
+
| --- | --- | --- |
|
|
401
|
+
| operation | <code>string</code> | Operation name |
|
|
402
|
+
| handler | <code>function</code> | Compensation handler function |
|
|
403
|
+
|
|
404
|
+
**Example**
|
|
405
|
+
```js
|
|
406
|
+
errorHandler.registerCompensation('create-order', async (context) => {
|
|
407
|
+
// Rollback order creation
|
|
408
|
+
await orderService.cancel(context.orderId);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
errorHandler.registerCompensation('charge-payment', async (context) => {
|
|
412
|
+
// Refund payment
|
|
413
|
+
await paymentService.refund(context.chargeId);
|
|
414
|
+
});
|
|
415
|
+
```
|
|
416
|
+
<a name="module_@onlineapps/conn-infra-error-handler..executeCompensation"></a>
|
|
417
|
+
|
|
418
|
+
### @onlineapps/conn-infra-error-handler~executeCompensation(operation, context) ⇒ <code>Promise.<\*></code>
|
|
419
|
+
Execute compensation for failed operation
|
|
420
|
+
|
|
421
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
422
|
+
**Returns**: <code>Promise.<\*></code> - Compensation result or null if no handler
|
|
423
|
+
**Throws**:
|
|
424
|
+
|
|
425
|
+
- <code>Error</code> If compensation fails
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
| Param | Type | Description |
|
|
429
|
+
| --- | --- | --- |
|
|
430
|
+
| operation | <code>string</code> | Operation that failed |
|
|
431
|
+
| context | <code>Object</code> | Operation context for compensation |
|
|
432
|
+
|
|
433
|
+
**Example**
|
|
434
|
+
```js
|
|
435
|
+
try {
|
|
436
|
+
await createOrder(data);
|
|
437
|
+
} catch (error) {
|
|
438
|
+
await errorHandler.executeCompensation('create-order', {
|
|
439
|
+
orderId: data.orderId,
|
|
440
|
+
userId: data.userId
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
```
|
|
444
|
+
<a name="module_@onlineapps/conn-infra-error-handler..routeToDLQ"></a>
|
|
445
|
+
|
|
446
|
+
### @onlineapps/conn-infra-error-handler~routeToDLQ(mqClient, message, error) ⇒ <code>Promise.<void></code>
|
|
447
|
+
Route failed message to dead letter queue
|
|
448
|
+
|
|
449
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
450
|
+
|
|
451
|
+
| Param | Type | Description |
|
|
452
|
+
| --- | --- | --- |
|
|
453
|
+
| mqClient | <code>Object</code> | Message queue client |
|
|
454
|
+
| message | <code>Object</code> | Original message that failed |
|
|
455
|
+
| error | <code>Error</code> | Error that occurred |
|
|
456
|
+
|
|
457
|
+
**Example**
|
|
458
|
+
```js
|
|
459
|
+
try {
|
|
460
|
+
await processMessage(message);
|
|
461
|
+
} catch (error) {
|
|
462
|
+
if (!errorHandler.shouldRetry(error)) {
|
|
463
|
+
await errorHandler.routeToDLQ(mqClient, message, error);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
<a name="module_@onlineapps/conn-infra-error-handler..createErrorResponse"></a>
|
|
468
|
+
|
|
469
|
+
### @onlineapps/conn-infra-error-handler~createErrorResponse(error, [context]) ⇒ <code>ErrorResponse</code>
|
|
470
|
+
Create standardized error response
|
|
471
|
+
|
|
472
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
473
|
+
**Returns**: <code>ErrorResponse</code> - Formatted error response
|
|
474
|
+
|
|
475
|
+
| Param | Type | Default | Description |
|
|
476
|
+
| --- | --- | --- | --- |
|
|
477
|
+
| error | <code>Error</code> | | Original error |
|
|
478
|
+
| [context] | <code>Object</code> | <code>{}</code> | Additional context |
|
|
479
|
+
|
|
480
|
+
**Example**
|
|
481
|
+
```js
|
|
482
|
+
const response = errorHandler.createErrorResponse(
|
|
483
|
+
new Error('Database connection failed'),
|
|
484
|
+
{ operation: 'user-fetch', userId: 123 }
|
|
485
|
+
);
|
|
486
|
+
// Returns standardized error object
|
|
487
|
+
```
|
|
488
|
+
<a name="module_@onlineapps/conn-infra-error-handler..wrap"></a>
|
|
489
|
+
|
|
490
|
+
### @onlineapps/conn-infra-error-handler~wrap(fn, [options]) ⇒ <code>function</code>
|
|
491
|
+
Wrap function with error handling capabilities
|
|
492
|
+
|
|
493
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
494
|
+
**Returns**: <code>function</code> - Wrapped function
|
|
495
|
+
|
|
496
|
+
| Param | Type | Default | Description |
|
|
497
|
+
| --- | --- | --- | --- |
|
|
498
|
+
| fn | <code>function</code> | | Function to wrap |
|
|
499
|
+
| [options] | <code>Object</code> | <code>{}</code> | Wrapping options |
|
|
500
|
+
| [options.name] | <code>string</code> | | Operation name |
|
|
501
|
+
| [options.circuitBreaker] | <code>boolean</code> | <code>true</code> | Use circuit breaker |
|
|
502
|
+
| [options.retry] | <code>boolean</code> | <code>true</code> | Use retry logic |
|
|
503
|
+
| [options.maxRetries] | <code>number</code> | | Max retry attempts |
|
|
504
|
+
|
|
505
|
+
**Example** *(Wrap API Function)*
|
|
506
|
+
```js
|
|
507
|
+
const safeApiCall = errorHandler.wrap(
|
|
508
|
+
async (id) => await api.getUser(id),
|
|
509
|
+
{ name: 'get-user', maxRetries: 3 }
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
const user = await safeApiCall(123);
|
|
513
|
+
```
|
|
514
|
+
**Example** *(Wrap Database Function)*
|
|
515
|
+
```js
|
|
516
|
+
const safeQuery = errorHandler.wrap(
|
|
517
|
+
async (sql, params) => await db.query(sql, params),
|
|
518
|
+
{ circuitBreaker: false, retry: true }
|
|
519
|
+
);
|
|
520
|
+
```
|
|
521
|
+
<a name="module_@onlineapps/conn-infra-error-handler..handleWorkflowError"></a>
|
|
522
|
+
|
|
523
|
+
### @onlineapps/conn-infra-error-handler~handleWorkflowError(workflow, error, failedStep) ⇒ <code>Promise.<WorkflowErrorResult></code>
|
|
524
|
+
Handle workflow error with compensation support
|
|
525
|
+
|
|
526
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
527
|
+
**Returns**: <code>Promise.<WorkflowErrorResult></code> - Error handling result
|
|
528
|
+
|
|
529
|
+
| Param | Type | Description |
|
|
530
|
+
| --- | --- | --- |
|
|
531
|
+
| workflow | <code>Object</code> | Workflow context |
|
|
532
|
+
| error | <code>Error</code> | Error that occurred |
|
|
533
|
+
| failedStep | <code>string</code> | Step that failed |
|
|
534
|
+
|
|
535
|
+
**Example**
|
|
536
|
+
```js
|
|
537
|
+
const result = await errorHandler.handleWorkflowError(
|
|
538
|
+
workflowContext,
|
|
539
|
+
error,
|
|
540
|
+
'payment-processing'
|
|
541
|
+
);
|
|
542
|
+
|
|
543
|
+
if (result.shouldRetry) {
|
|
544
|
+
// Retry the step
|
|
545
|
+
} else if (result.compensated) {
|
|
546
|
+
// Compensation was executed
|
|
547
|
+
}
|
|
548
|
+
```
|
|
549
|
+
<a name="module_@onlineapps/conn-infra-error-handler..getStats"></a>
|
|
550
|
+
|
|
551
|
+
### @onlineapps/conn-infra-error-handler~getStats() ⇒ <code>ErrorStats</code>
|
|
552
|
+
Get error handler statistics
|
|
553
|
+
|
|
554
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
555
|
+
**Returns**: <code>ErrorStats</code> - Current statistics
|
|
556
|
+
**Example**
|
|
557
|
+
```js
|
|
558
|
+
const stats = errorHandler.getStats();
|
|
559
|
+
console.log(`Total errors: ${stats.errors}`);
|
|
560
|
+
console.log(`Retry success rate: ${stats.retries / stats.errors * 100}%`);
|
|
561
|
+
console.log(`Circuit breakers:`, stats.circuitBreakers);
|
|
562
|
+
```
|
|
563
|
+
<a name="module_@onlineapps/conn-infra-error-handler..resetStats"></a>
|
|
564
|
+
|
|
565
|
+
### @onlineapps/conn-infra-error-handler~resetStats() ⇒ <code>void</code>
|
|
566
|
+
Reset all statistics
|
|
567
|
+
|
|
568
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
569
|
+
**Example**
|
|
570
|
+
```js
|
|
571
|
+
errorHandler.resetStats();
|
|
572
|
+
// All counters reset to 0
|
|
573
|
+
```
|
|
574
|
+
<a name="module_@onlineapps/conn-infra-error-handler..create"></a>
|
|
575
|
+
|
|
576
|
+
### @onlineapps/conn-infra-error-handler~create(config) ⇒ <code>ErrorHandlerConnector</code>
|
|
577
|
+
Factory function to create error handler instance
|
|
578
|
+
|
|
579
|
+
**Kind**: inner method of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
580
|
+
**Returns**: <code>ErrorHandlerConnector</code> - New error handler instance
|
|
581
|
+
|
|
582
|
+
| Param | Type | Description |
|
|
583
|
+
| --- | --- | --- |
|
|
584
|
+
| config | <code>Object</code> | Configuration object |
|
|
585
|
+
|
|
586
|
+
**Example**
|
|
587
|
+
```js
|
|
588
|
+
const errorHandler = ErrorHandlerConnector.create({
|
|
589
|
+
maxRetries: 5,
|
|
590
|
+
circuitBreakerEnabled: true
|
|
591
|
+
});
|
|
592
|
+
```
|
|
593
|
+
<a name="module_@onlineapps/conn-infra-error-handler..ErrorResponse"></a>
|
|
594
|
+
|
|
595
|
+
### @onlineapps/conn-infra-error-handler~ErrorResponse : <code>Object</code>
|
|
596
|
+
**Kind**: inner typedef of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
597
|
+
**Properties**
|
|
598
|
+
|
|
599
|
+
| Name | Type | Description |
|
|
600
|
+
| --- | --- | --- |
|
|
601
|
+
| success | <code>boolean</code> | Always false for errors |
|
|
602
|
+
| error | <code>Object</code> | Error details |
|
|
603
|
+
| error.message | <code>string</code> | Error message |
|
|
604
|
+
| error.code | <code>string</code> | Error code |
|
|
605
|
+
| error.type | <code>string</code> | Error type from ErrorTypes |
|
|
606
|
+
| error.retryable | <code>boolean</code> | Whether error is retryable |
|
|
607
|
+
| error.timestamp | <code>string</code> | ISO timestamp |
|
|
608
|
+
|
|
609
|
+
<a name="module_@onlineapps/conn-infra-error-handler..WorkflowErrorResult"></a>
|
|
610
|
+
|
|
611
|
+
### @onlineapps/conn-infra-error-handler~WorkflowErrorResult : <code>Object</code>
|
|
612
|
+
**Kind**: inner typedef of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
613
|
+
**Properties**
|
|
614
|
+
|
|
615
|
+
| Name | Type | Description |
|
|
616
|
+
| --- | --- | --- |
|
|
617
|
+
| handled | <code>boolean</code> | Whether error was handled |
|
|
618
|
+
| compensated | <code>boolean</code> | Whether compensation was executed |
|
|
619
|
+
| shouldContinue | <code>boolean</code> | Whether workflow should continue |
|
|
620
|
+
| shouldRetry | <code>boolean</code> | Whether step should be retried |
|
|
621
|
+
| error | <code>ErrorResponse</code> | Error response |
|
|
622
|
+
|
|
623
|
+
<a name="module_@onlineapps/conn-infra-error-handler..ErrorStats"></a>
|
|
624
|
+
|
|
625
|
+
### @onlineapps/conn-infra-error-handler~ErrorStats : <code>Object</code>
|
|
626
|
+
**Kind**: inner typedef of [<code>@onlineapps/conn-infra-error-handler</code>](#module_@onlineapps/conn-infra-error-handler)
|
|
627
|
+
**Properties**
|
|
628
|
+
|
|
629
|
+
| Name | Type | Description |
|
|
630
|
+
| --- | --- | --- |
|
|
631
|
+
| errors | <code>number</code> | Total errors |
|
|
632
|
+
| retries | <code>number</code> | Total retries |
|
|
633
|
+
| compensations | <code>number</code> | Total compensations |
|
|
634
|
+
| circuitBreaks | <code>number</code> | Circuit breaker trips |
|
|
635
|
+
| byType | <code>Object</code> | Errors by type |
|
|
636
|
+
| circuitBreakers | <code>Object</code> | Circuit breaker states |
|
|
637
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@onlineapps/conn-infra-error-handler",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Unified error handling with retry strategies, circuit breaker, and compensation patterns",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "jest",
|
|
8
|
+
"test:unit": "jest test/unit",
|
|
9
|
+
"test:integration": "jest test/integration",
|
|
10
|
+
"docs": "jsdoc2md --files src/**/*.js > API.md"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"error-handling",
|
|
14
|
+
"retry",
|
|
15
|
+
"circuit-breaker",
|
|
16
|
+
"compensation",
|
|
17
|
+
"resilience"
|
|
18
|
+
],
|
|
19
|
+
"author": "OA Drive Team",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"opossum": "^7.1.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"jest": "^29.7.0"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=14.0.0"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public",
|
|
32
|
+
"registry": "https://registry.npmjs.org/"
|
|
33
|
+
}
|
|
34
|
+
}
|