hide-a-bed 7.1.0 → 7.1.2
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 +148 -156
- package/dist/cjs/index.cjs +8 -4
- package/dist/esm/index.mjs +8 -4
- package/impl/bindConfig.mts +62 -69
- package/impl/headDB.mts +28 -28
- package/impl/utils/errors.mts +159 -189
- package/impl/utils/fetch.mts +94 -102
- package/impl/utils/logger.mts +12 -4
- package/index.mts +42 -55
- package/package.json +2 -2
- package/types/output/impl/bindConfig.d.mts +15 -15
- package/types/output/impl/bindConfig.d.mts.map +1 -1
- package/types/output/impl/headDB.d.mts +1 -1
- package/types/output/impl/headDB.d.mts.map +1 -1
- package/types/output/impl/utils/errors.d.mts +12 -12
- package/types/output/impl/utils/errors.d.mts.map +1 -1
- package/types/output/impl/utils/fetch.d.mts +4 -4
- package/types/output/impl/utils/fetch.d.mts.map +1 -1
- package/types/output/impl/utils/logger.d.mts.map +1 -1
- package/types/output/index.d.mts +35 -35
- package/types/output/index.d.mts.map +1 -1
package/impl/utils/errors.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getCouchError, getReason } from
|
|
2
|
-
import type { StandardSchemaV1 } from
|
|
3
|
-
import { isObject } from
|
|
1
|
+
import { getCouchError, getReason } from './response.mts'
|
|
2
|
+
import type { StandardSchemaV1 } from '../../types/standard-schema.ts'
|
|
3
|
+
import { isObject } from '../../types/types.utils.ts'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Represents a network-level error emitted by Node.js or HTTP client libraries.
|
|
@@ -11,42 +11,42 @@ export interface NetworkError {
|
|
|
11
11
|
/**
|
|
12
12
|
* Machine-readable error code describing the network failure.
|
|
13
13
|
*/
|
|
14
|
-
code: string
|
|
14
|
+
code: string
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Optional human-readable message supplied by the underlying library.
|
|
18
18
|
*/
|
|
19
|
-
message?: string
|
|
19
|
+
message?: string
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
type ErrorWithCause = {
|
|
23
|
-
cause?: unknown
|
|
24
|
-
}
|
|
23
|
+
cause?: unknown
|
|
24
|
+
}
|
|
25
25
|
|
|
26
26
|
export type ErrorCategory =
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
27
|
+
| 'conflict'
|
|
28
|
+
| 'network'
|
|
29
|
+
| 'not_found'
|
|
30
|
+
| 'operation'
|
|
31
|
+
| 'retryable'
|
|
32
|
+
| 'validation'
|
|
33
|
+
| 'transaction'
|
|
34
34
|
|
|
35
35
|
export type ErrorOperation =
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
49
|
-
const RETRYABLE_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504])
|
|
36
|
+
| 'get'
|
|
37
|
+
| 'getAtRev'
|
|
38
|
+
| 'getDBInfo'
|
|
39
|
+
| 'headDB'
|
|
40
|
+
| 'patch'
|
|
41
|
+
| 'patchDangerously'
|
|
42
|
+
| 'put'
|
|
43
|
+
| 'query'
|
|
44
|
+
| 'queryStream'
|
|
45
|
+
| 'remove'
|
|
46
|
+
| 'request'
|
|
47
|
+
| 'watchDocs'
|
|
48
|
+
|
|
49
|
+
const RETRYABLE_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504])
|
|
50
50
|
|
|
51
51
|
const NETWORK_ERROR_STATUS_MAP = {
|
|
52
52
|
ECONNREFUSED: 503,
|
|
@@ -56,53 +56,42 @@ const NETWORK_ERROR_STATUS_MAP = {
|
|
|
56
56
|
ENOTFOUND: 503,
|
|
57
57
|
EPIPE: 503,
|
|
58
58
|
EHOSTUNREACH: 503,
|
|
59
|
-
ESOCKETTIMEDOUT: 503
|
|
60
|
-
} as const satisfies Record<string, number
|
|
61
|
-
|
|
62
|
-
type NetworkErrorCode = keyof typeof NETWORK_ERROR_STATUS_MAP
|
|
63
|
-
|
|
64
|
-
const isNetworkError = (
|
|
65
|
-
value
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return (
|
|
70
|
-
typeof candidate.code === "string" &&
|
|
71
|
-
candidate.code in NETWORK_ERROR_STATUS_MAP
|
|
72
|
-
);
|
|
73
|
-
};
|
|
59
|
+
ESOCKETTIMEDOUT: 503
|
|
60
|
+
} as const satisfies Record<string, number>
|
|
61
|
+
|
|
62
|
+
type NetworkErrorCode = keyof typeof NETWORK_ERROR_STATUS_MAP
|
|
63
|
+
|
|
64
|
+
const isNetworkError = (value: unknown): value is NetworkError & { code: NetworkErrorCode } => {
|
|
65
|
+
if (typeof value !== 'object' || value === null) return false
|
|
66
|
+
const candidate = value as { code?: unknown }
|
|
67
|
+
return typeof candidate.code === 'string' && candidate.code in NETWORK_ERROR_STATUS_MAP
|
|
68
|
+
}
|
|
74
69
|
|
|
75
70
|
const getNestedNetworkError = (
|
|
76
|
-
value: unknown
|
|
71
|
+
value: unknown
|
|
77
72
|
): (NetworkError & { code: NetworkErrorCode }) | null => {
|
|
78
73
|
if (isNetworkError(value)) {
|
|
79
|
-
return value
|
|
74
|
+
return value
|
|
80
75
|
}
|
|
81
76
|
|
|
82
|
-
if (typeof value !==
|
|
83
|
-
return null
|
|
77
|
+
if (typeof value !== 'object' || value === null) {
|
|
78
|
+
return null
|
|
84
79
|
}
|
|
85
80
|
|
|
86
|
-
const candidate = value as ErrorWithCause
|
|
87
|
-
return isNetworkError(candidate.cause) ? candidate.cause : null
|
|
88
|
-
}
|
|
81
|
+
const candidate = value as ErrorWithCause
|
|
82
|
+
return isNetworkError(candidate.cause) ? candidate.cause : null
|
|
83
|
+
}
|
|
89
84
|
|
|
90
|
-
export const hasStatusCode = (
|
|
91
|
-
error
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
isObject(error) &&
|
|
95
|
-
"statusCode" in error &&
|
|
96
|
-
typeof error.statusCode === "number"
|
|
97
|
-
);
|
|
98
|
-
};
|
|
85
|
+
export const hasStatusCode = (error: unknown): error is { statusCode: number } => {
|
|
86
|
+
return isObject(error) && 'statusCode' in error && typeof error.statusCode === 'number'
|
|
87
|
+
}
|
|
99
88
|
|
|
100
89
|
export const isTransientAuthError = (error: unknown, attempt: number) => {
|
|
101
|
-
if (!hasStatusCode(error)) return false
|
|
102
|
-
if (attempt > 0) return false
|
|
90
|
+
if (!hasStatusCode(error)) return false
|
|
91
|
+
if (attempt > 0) return false
|
|
103
92
|
|
|
104
|
-
return error.statusCode === 401 || error.statusCode === 403
|
|
105
|
-
}
|
|
93
|
+
return error.statusCode === 401 || error.statusCode === 403
|
|
94
|
+
}
|
|
106
95
|
|
|
107
96
|
/**
|
|
108
97
|
* Shared structured fields available on hide-a-bed operational errors.
|
|
@@ -110,15 +99,15 @@ export const isTransientAuthError = (error: unknown, attempt: number) => {
|
|
|
110
99
|
* @public
|
|
111
100
|
*/
|
|
112
101
|
export type HideABedErrorOptions = {
|
|
113
|
-
category: ErrorCategory
|
|
114
|
-
cause?: unknown
|
|
115
|
-
couchError?: string
|
|
116
|
-
couchReason?: string
|
|
117
|
-
docId?: string
|
|
118
|
-
operation?: ErrorOperation
|
|
119
|
-
retryable: boolean
|
|
120
|
-
statusCode?: number
|
|
121
|
-
}
|
|
102
|
+
category: ErrorCategory
|
|
103
|
+
cause?: unknown
|
|
104
|
+
couchError?: string
|
|
105
|
+
couchReason?: string
|
|
106
|
+
docId?: string
|
|
107
|
+
operation?: ErrorOperation
|
|
108
|
+
retryable: boolean
|
|
109
|
+
statusCode?: number
|
|
110
|
+
}
|
|
122
111
|
|
|
123
112
|
/**
|
|
124
113
|
* Shared base class for operational errors thrown by hide-a-bed.
|
|
@@ -126,37 +115,34 @@ export type HideABedErrorOptions = {
|
|
|
126
115
|
* @public
|
|
127
116
|
*/
|
|
128
117
|
export class HideABedError extends Error {
|
|
129
|
-
readonly category: ErrorCategory
|
|
130
|
-
readonly couchError?: string
|
|
131
|
-
readonly couchReason?: string
|
|
132
|
-
readonly docId?: string
|
|
133
|
-
readonly operation?: ErrorOperation
|
|
134
|
-
readonly retryable: boolean
|
|
135
|
-
readonly statusCode?: number
|
|
118
|
+
readonly category: ErrorCategory
|
|
119
|
+
readonly couchError?: string
|
|
120
|
+
readonly couchReason?: string
|
|
121
|
+
readonly docId?: string
|
|
122
|
+
readonly operation?: ErrorOperation
|
|
123
|
+
readonly retryable: boolean
|
|
124
|
+
readonly statusCode?: number
|
|
136
125
|
|
|
137
126
|
constructor(message: string, options: HideABedErrorOptions) {
|
|
138
|
-
super(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
this.
|
|
143
|
-
this.
|
|
144
|
-
this.
|
|
145
|
-
this.
|
|
146
|
-
this.
|
|
147
|
-
this.operation = options.operation;
|
|
148
|
-
this.retryable = options.retryable;
|
|
149
|
-
this.statusCode = options.statusCode;
|
|
127
|
+
super(message, options.cause === undefined ? undefined : { cause: options.cause })
|
|
128
|
+
this.name = 'HideABedError'
|
|
129
|
+
this.category = options.category
|
|
130
|
+
this.couchError = options.couchError
|
|
131
|
+
this.couchReason = options.couchReason
|
|
132
|
+
this.docId = options.docId
|
|
133
|
+
this.operation = options.operation
|
|
134
|
+
this.retryable = options.retryable
|
|
135
|
+
this.statusCode = options.statusCode
|
|
150
136
|
}
|
|
151
137
|
}
|
|
152
138
|
|
|
153
139
|
export type ValidationErrorOptions = Omit<
|
|
154
140
|
Partial<HideABedErrorOptions>,
|
|
155
|
-
|
|
141
|
+
'category' | 'retryable'
|
|
156
142
|
> & {
|
|
157
|
-
issues: ReadonlyArray<StandardSchemaV1.Issue
|
|
158
|
-
message?: string
|
|
159
|
-
}
|
|
143
|
+
issues: ReadonlyArray<StandardSchemaV1.Issue>
|
|
144
|
+
message?: string
|
|
145
|
+
}
|
|
160
146
|
|
|
161
147
|
/**
|
|
162
148
|
* Error thrown when a requested CouchDB document cannot be found.
|
|
@@ -170,24 +156,21 @@ export type ValidationErrorOptions = Omit<
|
|
|
170
156
|
export class NotFoundError extends HideABedError {
|
|
171
157
|
constructor(
|
|
172
158
|
docId: string,
|
|
173
|
-
options: Omit<
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
> & {
|
|
177
|
-
message?: string;
|
|
178
|
-
} = {},
|
|
159
|
+
options: Omit<Partial<HideABedErrorOptions>, 'category' | 'docId' | 'retryable'> & {
|
|
160
|
+
message?: string
|
|
161
|
+
} = {}
|
|
179
162
|
) {
|
|
180
|
-
super(options.message ??
|
|
181
|
-
category:
|
|
182
|
-
couchError: options.couchError ??
|
|
163
|
+
super(options.message ?? 'Document not found', {
|
|
164
|
+
category: 'not_found',
|
|
165
|
+
couchError: options.couchError ?? 'not_found',
|
|
183
166
|
couchReason: options.couchReason,
|
|
184
167
|
cause: options.cause,
|
|
185
168
|
docId,
|
|
186
169
|
operation: options.operation,
|
|
187
170
|
retryable: false,
|
|
188
|
-
statusCode: options.statusCode ?? 404
|
|
189
|
-
})
|
|
190
|
-
this.name =
|
|
171
|
+
statusCode: options.statusCode ?? 404
|
|
172
|
+
})
|
|
173
|
+
this.name = 'NotFoundError'
|
|
191
174
|
}
|
|
192
175
|
}
|
|
193
176
|
|
|
@@ -199,24 +182,21 @@ export class NotFoundError extends HideABedError {
|
|
|
199
182
|
export class ConflictError extends HideABedError {
|
|
200
183
|
constructor(
|
|
201
184
|
docId: string,
|
|
202
|
-
options: Omit<
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
> & {
|
|
206
|
-
message?: string;
|
|
207
|
-
} = {},
|
|
185
|
+
options: Omit<Partial<HideABedErrorOptions>, 'category' | 'docId' | 'retryable'> & {
|
|
186
|
+
message?: string
|
|
187
|
+
} = {}
|
|
208
188
|
) {
|
|
209
|
-
super(options.message ??
|
|
210
|
-
category:
|
|
211
|
-
couchError: options.couchError ??
|
|
189
|
+
super(options.message ?? 'Document update conflict', {
|
|
190
|
+
category: 'conflict',
|
|
191
|
+
couchError: options.couchError ?? 'conflict',
|
|
212
192
|
couchReason: options.couchReason,
|
|
213
193
|
cause: options.cause,
|
|
214
194
|
docId,
|
|
215
195
|
operation: options.operation,
|
|
216
196
|
retryable: false,
|
|
217
|
-
statusCode: options.statusCode ?? 409
|
|
218
|
-
})
|
|
219
|
-
this.name =
|
|
197
|
+
statusCode: options.statusCode ?? 409
|
|
198
|
+
})
|
|
199
|
+
this.name = 'ConflictError'
|
|
220
200
|
}
|
|
221
201
|
}
|
|
222
202
|
|
|
@@ -228,21 +208,21 @@ export class ConflictError extends HideABedError {
|
|
|
228
208
|
export class OperationError extends HideABedError {
|
|
229
209
|
constructor(
|
|
230
210
|
message: string,
|
|
231
|
-
options: Omit<Partial<HideABedErrorOptions>,
|
|
232
|
-
category?: Extract<ErrorCategory,
|
|
233
|
-
} = {}
|
|
211
|
+
options: Omit<Partial<HideABedErrorOptions>, 'category' | 'retryable'> & {
|
|
212
|
+
category?: Extract<ErrorCategory, 'operation' | 'transaction'>
|
|
213
|
+
} = {}
|
|
234
214
|
) {
|
|
235
215
|
super(message, {
|
|
236
|
-
category: options.category ??
|
|
216
|
+
category: options.category ?? 'operation',
|
|
237
217
|
cause: options.cause,
|
|
238
218
|
couchError: options.couchError,
|
|
239
219
|
couchReason: options.couchReason,
|
|
240
220
|
docId: options.docId,
|
|
241
221
|
operation: options.operation,
|
|
242
222
|
retryable: false,
|
|
243
|
-
statusCode: options.statusCode
|
|
244
|
-
})
|
|
245
|
-
this.name =
|
|
223
|
+
statusCode: options.statusCode
|
|
224
|
+
})
|
|
225
|
+
this.name = 'OperationError'
|
|
246
226
|
}
|
|
247
227
|
}
|
|
248
228
|
|
|
@@ -252,21 +232,21 @@ export class OperationError extends HideABedError {
|
|
|
252
232
|
* @public
|
|
253
233
|
*/
|
|
254
234
|
export class ValidationError extends HideABedError {
|
|
255
|
-
readonly issues: ValidationErrorOptions[
|
|
235
|
+
readonly issues: ValidationErrorOptions['issues']
|
|
256
236
|
|
|
257
237
|
constructor(options: ValidationErrorOptions) {
|
|
258
|
-
super(options.message ??
|
|
259
|
-
category:
|
|
238
|
+
super(options.message ?? 'Validation failed', {
|
|
239
|
+
category: 'validation',
|
|
260
240
|
cause: options.cause,
|
|
261
241
|
couchError: options.couchError,
|
|
262
242
|
couchReason: options.couchReason,
|
|
263
243
|
docId: options.docId,
|
|
264
244
|
operation: options.operation,
|
|
265
245
|
retryable: false,
|
|
266
|
-
statusCode: options.statusCode
|
|
267
|
-
})
|
|
268
|
-
this.name =
|
|
269
|
-
this.issues = options.issues
|
|
246
|
+
statusCode: options.statusCode
|
|
247
|
+
})
|
|
248
|
+
this.name = 'ValidationError'
|
|
249
|
+
this.issues = options.issues
|
|
270
250
|
}
|
|
271
251
|
}
|
|
272
252
|
|
|
@@ -283,24 +263,21 @@ export class RetryableError extends HideABedError {
|
|
|
283
263
|
constructor(
|
|
284
264
|
message: string,
|
|
285
265
|
statusCode?: number,
|
|
286
|
-
options: Omit<
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
> & {
|
|
290
|
-
category?: Extract<ErrorCategory, "network" | "retryable">;
|
|
291
|
-
} = {},
|
|
266
|
+
options: Omit<Partial<HideABedErrorOptions>, 'category' | 'retryable' | 'statusCode'> & {
|
|
267
|
+
category?: Extract<ErrorCategory, 'network' | 'retryable'>
|
|
268
|
+
} = {}
|
|
292
269
|
) {
|
|
293
270
|
super(message, {
|
|
294
|
-
category: options.category ??
|
|
271
|
+
category: options.category ?? 'retryable',
|
|
295
272
|
cause: options.cause,
|
|
296
273
|
couchError: options.couchError,
|
|
297
274
|
couchReason: options.couchReason,
|
|
298
275
|
docId: options.docId,
|
|
299
276
|
operation: options.operation,
|
|
300
277
|
retryable: true,
|
|
301
|
-
statusCode
|
|
302
|
-
})
|
|
303
|
-
this.name =
|
|
278
|
+
statusCode
|
|
279
|
+
})
|
|
280
|
+
this.name = 'RetryableError'
|
|
304
281
|
}
|
|
305
282
|
|
|
306
283
|
/**
|
|
@@ -310,11 +287,9 @@ export class RetryableError extends HideABedError {
|
|
|
310
287
|
*
|
|
311
288
|
* @returns `true` if the status code is considered retryable; otherwise `false`.
|
|
312
289
|
*/
|
|
313
|
-
static isRetryableStatusCode(
|
|
314
|
-
statusCode
|
|
315
|
-
|
|
316
|
-
if (typeof statusCode !== "number") return false;
|
|
317
|
-
return RETRYABLE_STATUS_CODES.has(statusCode);
|
|
290
|
+
static isRetryableStatusCode(statusCode: number | undefined): statusCode is number {
|
|
291
|
+
if (typeof statusCode !== 'number') return false
|
|
292
|
+
return RETRYABLE_STATUS_CODES.has(statusCode)
|
|
318
293
|
}
|
|
319
294
|
|
|
320
295
|
/**
|
|
@@ -325,45 +300,42 @@ export class RetryableError extends HideABedError {
|
|
|
325
300
|
* @throws {@link RetryableError} When the error maps to a retryable network condition.
|
|
326
301
|
* @throws {*} Re-throws the original error when it cannot be mapped.
|
|
327
302
|
*/
|
|
328
|
-
static handleNetworkError(
|
|
329
|
-
err
|
|
330
|
-
operation: ErrorOperation = "request",
|
|
331
|
-
): never {
|
|
332
|
-
const networkError = getNestedNetworkError(err);
|
|
303
|
+
static handleNetworkError(err: unknown, operation: ErrorOperation = 'request'): never {
|
|
304
|
+
const networkError = getNestedNetworkError(err)
|
|
333
305
|
|
|
334
306
|
if (networkError) {
|
|
335
|
-
const statusCode = NETWORK_ERROR_STATUS_MAP[networkError.code]
|
|
307
|
+
const statusCode = NETWORK_ERROR_STATUS_MAP[networkError.code]
|
|
336
308
|
if (statusCode) {
|
|
337
|
-
throw new RetryableError(
|
|
338
|
-
category:
|
|
309
|
+
throw new RetryableError('Network request failed', statusCode, {
|
|
310
|
+
category: 'network',
|
|
339
311
|
cause: err,
|
|
340
|
-
operation
|
|
341
|
-
})
|
|
312
|
+
operation
|
|
313
|
+
})
|
|
342
314
|
}
|
|
343
315
|
}
|
|
344
316
|
|
|
345
|
-
throw err
|
|
317
|
+
throw err
|
|
346
318
|
}
|
|
347
319
|
}
|
|
348
320
|
|
|
349
321
|
type ResponseErrorOptions = {
|
|
350
|
-
body?: unknown
|
|
351
|
-
defaultMessage: string
|
|
352
|
-
docId?: string
|
|
353
|
-
notFoundMessage?: string
|
|
354
|
-
operation: ErrorOperation
|
|
355
|
-
statusCode?: number
|
|
356
|
-
}
|
|
322
|
+
body?: unknown
|
|
323
|
+
defaultMessage: string
|
|
324
|
+
docId?: string
|
|
325
|
+
notFoundMessage?: string
|
|
326
|
+
operation: ErrorOperation
|
|
327
|
+
statusCode?: number
|
|
328
|
+
}
|
|
357
329
|
|
|
358
330
|
const getResponseErrorMessage = (body: unknown, defaultMessage: string) => {
|
|
359
|
-
const reason = getReason(body,
|
|
331
|
+
const reason = getReason(body, '').trim()
|
|
360
332
|
|
|
361
333
|
if (!reason || reason === defaultMessage) {
|
|
362
|
-
return defaultMessage
|
|
334
|
+
return defaultMessage
|
|
363
335
|
}
|
|
364
336
|
|
|
365
|
-
return `${defaultMessage}: ${reason}
|
|
366
|
-
}
|
|
337
|
+
return `${defaultMessage}: ${reason}`
|
|
338
|
+
}
|
|
367
339
|
|
|
368
340
|
export function createResponseError({
|
|
369
341
|
body,
|
|
@@ -371,22 +343,20 @@ export function createResponseError({
|
|
|
371
343
|
docId,
|
|
372
344
|
notFoundMessage,
|
|
373
345
|
operation,
|
|
374
|
-
statusCode
|
|
346
|
+
statusCode
|
|
375
347
|
}: ResponseErrorOptions): HideABedError {
|
|
376
|
-
const couchError = getCouchError(body)
|
|
377
|
-
const couchReason = getReason(body,
|
|
378
|
-
const message = getResponseErrorMessage(body, defaultMessage)
|
|
348
|
+
const couchError = getCouchError(body)
|
|
349
|
+
const couchReason = getReason(body, '').trim() || undefined
|
|
350
|
+
const message = getResponseErrorMessage(body, defaultMessage)
|
|
379
351
|
|
|
380
352
|
if (statusCode === 404 && docId) {
|
|
381
353
|
return new NotFoundError(docId, {
|
|
382
354
|
couchError,
|
|
383
355
|
couchReason,
|
|
384
|
-
message: notFoundMessage
|
|
385
|
-
? getResponseErrorMessage(body, notFoundMessage)
|
|
386
|
-
: undefined,
|
|
356
|
+
message: notFoundMessage ? getResponseErrorMessage(body, notFoundMessage) : undefined,
|
|
387
357
|
operation,
|
|
388
|
-
statusCode
|
|
389
|
-
})
|
|
358
|
+
statusCode
|
|
359
|
+
})
|
|
390
360
|
}
|
|
391
361
|
|
|
392
362
|
if (statusCode === 409 && docId) {
|
|
@@ -395,16 +365,16 @@ export function createResponseError({
|
|
|
395
365
|
couchReason,
|
|
396
366
|
message,
|
|
397
367
|
operation,
|
|
398
|
-
statusCode
|
|
399
|
-
})
|
|
368
|
+
statusCode
|
|
369
|
+
})
|
|
400
370
|
}
|
|
401
371
|
|
|
402
372
|
if (RetryableError.isRetryableStatusCode(statusCode)) {
|
|
403
373
|
return new RetryableError(message, statusCode, {
|
|
404
374
|
couchError,
|
|
405
375
|
couchReason,
|
|
406
|
-
operation
|
|
407
|
-
})
|
|
376
|
+
operation
|
|
377
|
+
})
|
|
408
378
|
}
|
|
409
379
|
|
|
410
380
|
return new OperationError(message, {
|
|
@@ -412,13 +382,13 @@ export function createResponseError({
|
|
|
412
382
|
couchReason,
|
|
413
383
|
docId,
|
|
414
384
|
operation,
|
|
415
|
-
statusCode
|
|
416
|
-
})
|
|
385
|
+
statusCode
|
|
386
|
+
})
|
|
417
387
|
}
|
|
418
388
|
|
|
419
389
|
export function isConflictError(err: unknown): boolean {
|
|
420
|
-
if (err instanceof ConflictError) return true
|
|
421
|
-
if (typeof err !==
|
|
422
|
-
const candidate = err as { statusCode?: unknown }
|
|
423
|
-
return candidate.statusCode === 409
|
|
390
|
+
if (err instanceof ConflictError) return true
|
|
391
|
+
if (typeof err !== 'object' || err === null) return false
|
|
392
|
+
const candidate = err as { statusCode?: unknown }
|
|
393
|
+
return candidate.statusCode === 409
|
|
424
394
|
}
|