Skip to content

Commit 4137f67

Browse files
author
Volodymyr Malyhin
committed
chore: fix build
1 parent 341bf3a commit 4137f67

File tree

2 files changed

+61
-103
lines changed

2 files changed

+61
-103
lines changed

registry/server/util/axiosErrorTransformer.ts

Lines changed: 2 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,11 @@
11
import { type AxiosError, type RawAxiosResponseHeaders, type AxiosResponseHeaders } from 'axios';
22
import { extendError } from './extendError';
3+
import { sanitizeHeaders, truncateBody } from './helpers';
34

45
const IlcAxiosError = extendError('AxiosError');
56

6-
const SENSITIVE_HEADERS = ['authorization', 'cookie', 'set-cookie', 'x-api-key', 'x-auth-token', 'proxy-authorization'];
7-
8-
const MAX_BODY_LENGTH = 1000;
9-
107
type HeadersInput = RawAxiosResponseHeaders | AxiosResponseHeaders | Record<string, unknown> | undefined;
118

12-
/**
13-
* Sanitizes headers by redacting sensitive values
14-
*/
15-
export function sanitizeHeaders(headers: HeadersInput): Record<string, unknown> | undefined {
16-
if (!headers || typeof headers !== 'object') {
17-
return undefined;
18-
}
19-
20-
const sanitized: Record<string, unknown> = {};
21-
22-
for (const [key, value] of Object.entries(headers)) {
23-
const lowerKey = key.toLowerCase();
24-
if (SENSITIVE_HEADERS.includes(lowerKey)) {
25-
sanitized[key] = '[REDACTED]';
26-
} else {
27-
sanitized[key] = value;
28-
}
29-
}
30-
31-
return sanitized;
32-
}
33-
34-
/**
35-
* Truncates body content if too large, returns metadata for non-string bodies
36-
*/
37-
export function truncateBody(body: unknown): { content: unknown; truncated?: boolean; type?: string; length?: number } {
38-
if (body === undefined || body === null) {
39-
return { content: body };
40-
}
41-
42-
// Handle string bodies
43-
if (typeof body === 'string') {
44-
if (body.length > MAX_BODY_LENGTH) {
45-
return {
46-
content: body.substring(0, MAX_BODY_LENGTH),
47-
truncated: true,
48-
length: body.length,
49-
};
50-
}
51-
return { content: body };
52-
}
53-
54-
// Handle objects - try to stringify
55-
if (typeof body === 'object') {
56-
try {
57-
const stringified = JSON.stringify(body);
58-
if (stringified.length > MAX_BODY_LENGTH) {
59-
return {
60-
content: stringified.substring(0, MAX_BODY_LENGTH),
61-
truncated: true,
62-
length: stringified.length,
63-
type: 'object',
64-
};
65-
}
66-
return { content: body };
67-
} catch {
68-
// Circular reference or non-serializable
69-
return {
70-
content: '[Non-serializable object]',
71-
type: typeof body,
72-
};
73-
}
74-
}
75-
76-
// Handle other types (number, boolean, etc.)
77-
return { content: body };
78-
}
79-
80-
/**
81-
* Safely stringifies a value, handling circular references
82-
*/
83-
export function safeStringify(value: unknown): string | undefined {
84-
if (value === undefined || value === null) {
85-
return undefined;
86-
}
87-
88-
try {
89-
return JSON.stringify(value);
90-
} catch {
91-
return '[Circular or non-serializable]';
92-
}
93-
}
94-
959
export function isAxiosError(err: unknown): err is AxiosError {
9610
return Boolean((err as AxiosError)?.isAxiosError);
9711
}
@@ -103,18 +17,13 @@ interface NetworkErrorDetails {
10317
cause?: string;
10418
}
10519

106-
/**
107-
* Extracts network-level error details from an AxiosError
108-
*/
10920
function getNetworkErrorDetails(err: AxiosError): NetworkErrorDetails {
11021
const details: NetworkErrorDetails = {};
11122

112-
// err.code contains network error codes like ECONNREFUSED, ETIMEDOUT, etc.
11323
if (err.code) {
11424
details.code = err.code;
11525
}
11626

117-
// Access low-level error properties if available
11827
const anyErr = err as unknown as Record<string, unknown>;
11928
if (typeof anyErr.errno === 'number' || typeof anyErr.errno === 'string') {
12029
details.errno = anyErr.errno;
@@ -123,7 +32,6 @@ function getNetworkErrorDetails(err: AxiosError): NetworkErrorDetails {
12332
details.syscall = anyErr.syscall;
12433
}
12534

126-
// Extract cause message if available
12735
if (err.cause instanceof Error) {
12836
details.cause = err.cause.message;
12937
} else if (typeof err.cause === 'string') {
@@ -133,15 +41,11 @@ function getNetworkErrorDetails(err: AxiosError): NetworkErrorDetails {
13341
return details;
13442
}
13543

136-
/**
137-
* Generates a meaningful error message, with fallback for network errors
138-
*/
13944
function getErrorMessage(err: AxiosError): string {
14045
if (err.message) {
14146
return err.message;
14247
}
14348

144-
// Fallback for network errors that may have empty message
14549
if (err.code) {
14650
const url = err.config?.url || 'unknown URL';
14751
return `${err.code}: ${url}`;
@@ -162,27 +66,22 @@ export function axiosErrorTransformer<T = unknown>(err: T): typeof IlcAxiosError
16266
return new IlcAxiosError({
16367
message: getErrorMessage(err),
16468
data: {
165-
// Existing fields (preserved for backward compatibility)
16669
response: {
16770
status: err.response?.status,
16871
statusText: err.response?.statusText,
16972
data: responseBody.content,
17073
dataTruncated: responseBody.truncated,
17174
dataLength: responseBody.length,
172-
headers: sanitizeHeaders(err.response?.headers),
75+
headers: sanitizeHeaders(err.response?.headers as HeadersInput),
17376
},
17477
url: err.config?.url,
17578
method: err.config?.method,
17679
payload: requestPayload.content,
17780
payloadTruncated: requestPayload.truncated,
17881
payloadLength: requestPayload.length,
17982
headers: sanitizeHeaders(err.config?.headers as HeadersInput),
180-
181-
// New fields for enhanced diagnostics
18283
baseURL: err.config?.baseURL,
18384
timeout: err.config?.timeout,
184-
185-
// Network error details
18685
...networkDetails,
18786
},
18887
});

registry/server/util/helpers.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,62 @@ export function setErrorData(error: Error, data: Record<string, string | number
3838
Object.defineProperty(error, 'data', { enumerable: true, writable: false, value: data });
3939
}
4040
}
41+
42+
const SENSITIVE_HEADERS = ['authorization', 'cookie', 'set-cookie', 'x-api-key', 'x-auth-token', 'proxy-authorization'];
43+
const MAX_BODY_LENGTH = 1000;
44+
45+
export function sanitizeHeaders(headers: Record<string, unknown> | undefined): Record<string, unknown> | undefined {
46+
if (!headers || typeof headers !== 'object') {
47+
return undefined;
48+
}
49+
50+
const sanitized: Record<string, unknown> = {};
51+
52+
for (const [key, value] of Object.entries(headers)) {
53+
const lowerKey = key.toLowerCase();
54+
if (!SENSITIVE_HEADERS.includes(lowerKey)) {
55+
sanitized[key] = value;
56+
}
57+
}
58+
59+
return sanitized;
60+
}
61+
62+
export function truncateBody(body: unknown): { content: unknown; truncated?: boolean; type?: string; length?: number } {
63+
if (body === undefined || body === null) {
64+
return { content: body };
65+
}
66+
67+
if (typeof body === 'string') {
68+
if (body.length > MAX_BODY_LENGTH) {
69+
return {
70+
content: body.substring(0, MAX_BODY_LENGTH),
71+
truncated: true,
72+
length: body.length,
73+
};
74+
}
75+
return { content: body };
76+
}
77+
78+
if (typeof body === 'object') {
79+
try {
80+
const stringified = JSON.stringify(body);
81+
if (stringified.length > MAX_BODY_LENGTH) {
82+
return {
83+
content: stringified.substring(0, MAX_BODY_LENGTH),
84+
truncated: true,
85+
length: stringified.length,
86+
type: 'object',
87+
};
88+
}
89+
return { content: body };
90+
} catch {
91+
return {
92+
content: '[Non-serializable object]',
93+
type: typeof body,
94+
};
95+
}
96+
}
97+
98+
return { content: body };
99+
}

0 commit comments

Comments
 (0)