-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy patherror-handler.ts
More file actions
129 lines (107 loc) · 3.64 KB
/
error-handler.ts
File metadata and controls
129 lines (107 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { errors } from '@feathersjs/errors'
import { ElasticsearchError } from './types'
/**
* Maps Elasticsearch error codes to Feathers error types
*/
const ERROR_MAP: Record<number, string> = {
400: 'BadRequest',
401: 'NotAuthenticated',
403: 'Forbidden',
404: 'NotFound',
409: 'Conflict',
422: 'Unprocessable',
500: 'GeneralError',
501: 'NotImplemented',
502: 'BadGateway',
503: 'Unavailable'
}
/**
* Formats error message with additional context
*/
function formatErrorMessage(error: ElasticsearchError, context?: string): string {
const baseMessage = error.message || 'An error occurred'
const esMessage = error.meta?.body?.error?.reason || error.meta?.body?.error?.type || ''
if (context && esMessage) {
return `${context}: ${esMessage}`
} else if (esMessage) {
return esMessage
}
return context ? `${context}: ${baseMessage}` : baseMessage
}
/**
* Extracts detailed error information from Elasticsearch response
*/
function extractErrorDetails(error: ElasticsearchError): Record<string, unknown> | undefined {
const details: Record<string, unknown> = {}
if (error.meta?.body?.error) {
const esError = error.meta.body.error
if (esError.caused_by) {
details.causedBy = esError.caused_by.reason
}
if (esError.root_cause) {
details.rootCause = esError.root_cause.map((cause: { type?: string; reason?: string }) => ({
type: cause.type,
reason: cause.reason
}))
}
if (esError.failures) {
details.failures = esError.failures
}
}
return Object.keys(details).length > 0 ? details : undefined
}
/**
* Handles Elasticsearch errors and converts them to Feathers errors
* @param error - The Elasticsearch error
* @param id - Optional document ID for context
* @param context - Optional context string for better error messages
* @returns Feathers error
*/
export function errorHandler(
error: ElasticsearchError | Error,
id?: string | number,
context?: string
): Error {
// If already a Feathers error, just return it
if ((error as { className?: string }).className) {
return error
}
// Type guard for ElasticsearchError
const esError = error as ElasticsearchError
// Check for specific error types first
if (
esError.meta?.body?.error?.type === 'version_conflict_engine_exception' ||
(esError.name === 'ResponseError' && esError.meta?.statusCode === 409) ||
esError.meta?.body?.status === 409
) {
const message = formatErrorMessage(esError, context)
return new errors.Conflict(message, { id })
}
// Extract status code from various error formats
const statusCode =
esError.statusCode || esError.status || esError.meta?.statusCode || esError.meta?.body?.status || 500
// Get the appropriate error class
const ErrorClass = ERROR_MAP[statusCode]
type FeathersErrorConstructor = new (message: string, data?: Record<string, unknown>) => Error
const errorsMap = errors as unknown as Record<string, FeathersErrorConstructor>
if (!ErrorClass || !errorsMap[ErrorClass]) {
// Fallback to GeneralError for unknown status codes
const message = formatErrorMessage(error, context)
const details = extractErrorDetails(error)
return new errors.GeneralError(message, {
statusCode,
...(details && { details }),
...(id && { id })
})
}
// Create the appropriate Feathers error
const message = formatErrorMessage(error, context)
const details = extractErrorDetails(error)
const FeathersError = errorsMap[ErrorClass]
return new FeathersError(message, {
...(details && { details }),
...(id && { id })
})
}
// Default export for backward compatibility
export default errorHandler