| 1 | import pino from 'pino' |
| 2 | |
| 3 | export function serializeError(error: unknown): unknown { |
| 4 | if (!(error instanceof Error)) { |
| 5 | return error |
| 6 | } |
| 7 | |
| 8 | const serialized = pino.stdSerializers.errWithCause(error) |
| 9 | pruneAxiosSocketData(serialized) |
| 10 | return serialized |
| 11 | } |
| 12 | |
| 13 | function pruneAxiosSocketData(value: unknown): void { |
| 14 | if (!isRecord(value)) { |
| 15 | return |
| 16 | } |
| 17 | |
| 18 | if (isAxiosErrorLike(value)) { |
| 19 | Object.setPrototypeOf(value, Object.prototype) |
| 20 | delete value['request'] |
| 21 | delete value['raw'] |
| 22 | |
| 23 | const response = value['response'] |
| 24 | if (isRecord(response)) { |
| 25 | delete response['request'] |
| 26 | delete response['req'] |
| 27 | delete response['socket'] |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | pruneAxiosSocketData(value['cause']) |
| 32 | |
| 33 | const aggregateErrors = value['aggregateErrors'] |
| 34 | if (Array.isArray(aggregateErrors)) { |
| 35 | for (const error of aggregateErrors) { |
| 36 | pruneAxiosSocketData(error) |
| 37 | } |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | function isAxiosErrorLike(value: Record<string, unknown>): boolean { |
| 42 | return value['isAxiosError'] === true |
| 43 | || value['type'] === 'AxiosError' |
| 44 | || value['name'] === 'AxiosError' |
| 45 | } |
| 46 | |
| 47 | function isRecord(value: unknown): value is Record<string, unknown> { |
| 48 | return typeof value === 'object' && value !== null |
| 49 | } |
| 50 |