Skip to content

Commit 33a8fe2

Browse files
MichaelGHSegclaude
andauthored
feat: httpConfig CDN support for retry-settings tests (#1188)
* feat: read httpConfig from CDN integration settings and honor enabled flags - Read httpConfig from integrations["Segment.io"] in SegmentDestination.update(), falling back to top-level CDN config via analytics.getHttpConfig() - Add backoffEnabled parameter to classifyError() so that transient errors are classified as permanent when backoffConfig.enabled is false - Also handle rateLimitEnabled + statusCodeOverrides interaction when the relevant config is disabled - Add retry-settings test suite to e2e-config.json Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use explicit comparison to satisfy strict-boolean-expressions lint Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 365f29d commit 33a8fe2

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

e2e-cli/e2e-config.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
{
22
"sdk": "react-native",
3-
"test_suites": "basic,settings,retry",
3+
"test_suites": "basic,settings,retry,retry-settings",
44
"auto_settings": true,
55
"patch": null,
66
"env": {
7-
"BROWSER_BATCHING": "true"
7+
"BROWSER_BATCHING": "true",
8+
"HTTP_CONFIG_SETTINGS": "true"
89
}
910
}

packages/core/src/errors.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,31 +147,47 @@ export const classifyError = (
147147
default5xxBehavior?: 'drop' | 'retry';
148148
statusCodeOverrides?: Record<string, 'drop' | 'retry'>;
149149
rateLimitEnabled?: boolean;
150+
backoffEnabled?: boolean;
150151
}
151152
): ErrorClassification => {
152153
const override = config?.statusCodeOverrides?.[statusCode.toString()];
153154
if (override !== undefined) {
154155
if (override === 'retry') {
156+
// If the relevant config is disabled, treat retry overrides as permanent
157+
if (statusCode === 429 && config?.rateLimitEnabled === false) {
158+
return new ErrorClassification('permanent');
159+
}
160+
if (statusCode !== 429 && config?.backoffEnabled === false) {
161+
return new ErrorClassification('permanent');
162+
}
155163
return statusCode === 429
156164
? new ErrorClassification('rate_limit')
157165
: new ErrorClassification('transient');
158166
}
159167
return new ErrorClassification('permanent');
160168
}
161169

162-
if (statusCode === 429 && config?.rateLimitEnabled !== false) {
163-
return new ErrorClassification('rate_limit');
170+
if (statusCode === 429) {
171+
return config?.rateLimitEnabled !== false
172+
? new ErrorClassification('rate_limit')
173+
: new ErrorClassification('permanent');
164174
}
165175

166176
if (statusCode >= 400 && statusCode < 500) {
167177
const behavior = config?.default4xxBehavior ?? 'drop';
178+
if (behavior === 'retry' && config?.backoffEnabled === false) {
179+
return new ErrorClassification('permanent');
180+
}
168181
return new ErrorClassification(
169182
behavior === 'retry' ? 'transient' : 'permanent'
170183
);
171184
}
172185

173186
if (statusCode >= 500 && statusCode < 600) {
174187
const behavior = config?.default5xxBehavior ?? 'retry';
188+
if (behavior === 'retry' && config?.backoffEnabled === false) {
189+
return new ErrorClassification('permanent');
190+
}
175191
return new ErrorClassification(
176192
behavior === 'retry' ? 'transient' : 'permanent'
177193
);

packages/core/src/plugins/SegmentDestination.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
} from '../errors';
2626
import { RetryManager } from '../backoff/RetryManager';
2727
import type { RetryResult } from '../backoff';
28+
import { extractHttpConfig } from '../config-validation';
2829

2930
const MAX_EVENTS_PER_BATCH = 100;
3031
const MAX_PAYLOAD_SIZE_IN_KB = 500;
@@ -86,6 +87,7 @@ export class SegmentDestination extends DestinationPlugin {
8687
default5xxBehavior: this.getBackoffConfig()?.default5xxBehavior,
8788
statusCodeOverrides: this.getBackoffConfig()?.statusCodeOverrides,
8889
rateLimitEnabled: this.getRateLimitConfig()?.enabled,
90+
backoffEnabled: this.getBackoffConfig()?.enabled,
8991
});
9092

9193
switch (classification.errorType) {
@@ -419,7 +421,22 @@ export class SegmentDestination extends DestinationPlugin {
419421
this.apiHost = `https://${segmentSettings.apiHost}/b`;
420422
}
421423

422-
const httpConfig = this.analytics?.getHttpConfig();
424+
// Read httpConfig: prefer integration-level settings from CDN, fall back to
425+
// top-level CDN config merged with client config (via analytics.getHttpConfig()).
426+
const rawIntegration = settings.integrations[this.key] as
427+
| Record<string, unknown>
428+
| undefined;
429+
let httpConfig: HttpConfig | undefined;
430+
if (rawIntegration?.httpConfig !== undefined) {
431+
httpConfig = extractHttpConfig(
432+
rawIntegration.httpConfig as HttpConfig,
433+
this.analytics?.logger
434+
);
435+
}
436+
if (!httpConfig) {
437+
httpConfig = this.analytics?.getHttpConfig();
438+
}
439+
423440
if (httpConfig) {
424441
this.httpConfig = httpConfig;
425442

0 commit comments

Comments
 (0)