fix(api): fail fast on dead PartsCatalogs proxy ports + tunable timeouts
The PartsCatalogs ProxyAgent had no connect timeout, so a dead DataImpulse proxy port stalled for undici's 10s default before the retry rotated to a fresh port (prod: "ConnectTimeoutError ... 74.81.81.81:10628, timeout: 10000ms"). Three such stalls exceed the caller's 25s decode budget, turning a transient bad port into a hard decode failure. Set an explicit 6s proxy connect timeout so retries rotate to a live port within budget, and make the request timeout / retry count / connect timeout env-tunable (PCAT_REQUEST_TIMEOUT_MS, PCAT_MAX_RETRIES, PCAT_PROXY_CONNECT_TIMEOUT_MS) with the current values as defaults. Phase 2 of 4 on decode reliability. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,12 @@ import {
|
|||||||
} from "./parts-catalogs.types";
|
} from "./parts-catalogs.types";
|
||||||
|
|
||||||
const API_BASE = "https://gui.parts-catalogs.com/v3/api/proxy";
|
const API_BASE = "https://gui.parts-catalogs.com/v3/api/proxy";
|
||||||
const REQUEST_TIMEOUT = 30_000;
|
const REQUEST_TIMEOUT = Number(process.env.PCAT_REQUEST_TIMEOUT_MS) || 30_000;
|
||||||
|
const MAX_RETRIES = Number(process.env.PCAT_MAX_RETRIES) || 2;
|
||||||
|
// A dead DataImpulse proxy port otherwise stalls for undici's 10s default connect
|
||||||
|
// timeout before the retry rotates to a fresh port — three of those blow the
|
||||||
|
// caller's 25s decode budget. Fail fast so retries reach a live port in time.
|
||||||
|
const PROXY_CONNECT_TIMEOUT = Number(process.env.PCAT_PROXY_CONNECT_TIMEOUT_MS) || 6_000;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PartsCatalogsService {
|
export class PartsCatalogsService {
|
||||||
@@ -188,7 +193,7 @@ export class PartsCatalogsService {
|
|||||||
params?: Record<string, string>,
|
params?: Record<string, string>,
|
||||||
externalSignal?: AbortSignal,
|
externalSignal?: AbortSignal,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const maxRetries = 2;
|
const maxRetries = MAX_RETRIES;
|
||||||
|
|
||||||
let session: PcatSession | null = null;
|
let session: PcatSession | null = null;
|
||||||
|
|
||||||
@@ -227,7 +232,10 @@ export class PartsCatalogsService {
|
|||||||
// Use undici ProxyAgent if proxy is configured
|
// Use undici ProxyAgent if proxy is configured
|
||||||
if (session.proxyUrl) {
|
if (session.proxyUrl) {
|
||||||
const { ProxyAgent } = await import("undici");
|
const { ProxyAgent } = await import("undici");
|
||||||
fetchOptions.dispatcher = new ProxyAgent(session.proxyUrl);
|
fetchOptions.dispatcher = new ProxyAgent({
|
||||||
|
uri: session.proxyUrl,
|
||||||
|
connect: { timeout: PROXY_CONNECT_TIMEOUT },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(url.toString(), fetchOptions);
|
const response = await fetch(url.toString(), fetchOptions);
|
||||||
|
|||||||
Reference in New Issue
Block a user