Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions e2e-cli/e2e-config.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"sdk": "react-native",
"test_suites": "basic,settings,retry",
"test_suites": "basic,settings,retry,retry-settings",
"auto_settings": true,
"patch": null,
"env": {
"BROWSER_BATCHING": "true"
"BROWSER_BATCHING": "true",
"HTTP_CONFIG_SETTINGS": "true"
}
}
20 changes: 18 additions & 2 deletions packages/core/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,31 +147,47 @@ export const classifyError = (
default5xxBehavior?: 'drop' | 'retry';
statusCodeOverrides?: Record<string, 'drop' | 'retry'>;
rateLimitEnabled?: boolean;
backoffEnabled?: boolean;
}
): ErrorClassification => {
const override = config?.statusCodeOverrides?.[statusCode.toString()];
if (override !== undefined) {
if (override === 'retry') {
// If the relevant config is disabled, treat retry overrides as permanent
if (statusCode === 429 && config?.rateLimitEnabled === false) {
return new ErrorClassification('permanent');
}
if (statusCode !== 429 && config?.backoffEnabled === false) {
return new ErrorClassification('permanent');
}
return statusCode === 429
? new ErrorClassification('rate_limit')
: new ErrorClassification('transient');
}
return new ErrorClassification('permanent');
}

if (statusCode === 429 && config?.rateLimitEnabled !== false) {
return new ErrorClassification('rate_limit');
if (statusCode === 429) {
return config?.rateLimitEnabled !== false
? new ErrorClassification('rate_limit')
: new ErrorClassification('permanent');
}

if (statusCode >= 400 && statusCode < 500) {
const behavior = config?.default4xxBehavior ?? 'drop';
if (behavior === 'retry' && config?.backoffEnabled === false) {
return new ErrorClassification('permanent');
}
return new ErrorClassification(
behavior === 'retry' ? 'transient' : 'permanent'
);
}

if (statusCode >= 500 && statusCode < 600) {
const behavior = config?.default5xxBehavior ?? 'retry';
if (behavior === 'retry' && config?.backoffEnabled === false) {
return new ErrorClassification('permanent');
}
return new ErrorClassification(
behavior === 'retry' ? 'transient' : 'permanent'
);
Expand Down
19 changes: 18 additions & 1 deletion packages/core/src/plugins/SegmentDestination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
} from '../errors';
import { RetryManager } from '../backoff/RetryManager';
import type { RetryResult } from '../backoff';
import { extractHttpConfig } from '../config-validation';

const MAX_EVENTS_PER_BATCH = 100;
const MAX_PAYLOAD_SIZE_IN_KB = 500;
Expand Down Expand Up @@ -86,6 +87,7 @@ export class SegmentDestination extends DestinationPlugin {
default5xxBehavior: this.getBackoffConfig()?.default5xxBehavior,
statusCodeOverrides: this.getBackoffConfig()?.statusCodeOverrides,
rateLimitEnabled: this.getRateLimitConfig()?.enabled,
backoffEnabled: this.getBackoffConfig()?.enabled,
});

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

const httpConfig = this.analytics?.getHttpConfig();
// Read httpConfig: prefer integration-level settings from CDN, fall back to
// top-level CDN config merged with client config (via analytics.getHttpConfig()).
const rawIntegration = settings.integrations[this.key] as
| Record<string, unknown>
| undefined;
let httpConfig: HttpConfig | undefined;
if (rawIntegration?.httpConfig !== undefined) {
httpConfig = extractHttpConfig(
rawIntegration.httpConfig as HttpConfig,
this.analytics?.logger
);
}
if (!httpConfig) {
httpConfig = this.analytics?.getHttpConfig();
}

if (httpConfig) {
this.httpConfig = httpConfig;

Expand Down
Loading