diff --git a/packages/sdk/browser/src/platform/DefaultBrowserEventSource.ts b/packages/sdk/browser/src/platform/DefaultBrowserEventSource.ts index d753931aa8..55878a5968 100644 --- a/packages/sdk/browser/src/platform/DefaultBrowserEventSource.ts +++ b/packages/sdk/browser/src/platform/DefaultBrowserEventSource.ts @@ -97,7 +97,7 @@ export default class DefaultBrowserEventSource implements LDEventSource { // The event source may not produce a status. But the LaunchDarkly // polyfill can. If we can get the status, then we should stop retrying // on certain error codes. - if (err.status && typeof err.status === 'number' && !this._errorFilter(err)) { + if (typeof err.status === 'number' && !this._errorFilter(err)) { // If we encounter an unrecoverable condition, then we do not want to // retry anymore. return; diff --git a/packages/shared/sdk-client/src/datasource/fdv2/StreamingFDv2Base.ts b/packages/shared/sdk-client/src/datasource/fdv2/StreamingFDv2Base.ts index 890cca3e35..e6d3486767 100644 --- a/packages/shared/sdk-client/src/datasource/fdv2/StreamingFDv2Base.ts +++ b/packages/shared/sdk-client/src/datasource/fdv2/StreamingFDv2Base.ts @@ -188,7 +188,10 @@ export function createStreamingBase(config: { } if (!event?.data) { - config.logger?.warn(`Event from EventStream missing data for "${eventName}".`); + // Some events (e.g. 'error') may legitimately arrive without a body. + if (eventName !== 'error') { + config.logger?.warn(`Event from EventStream missing data for "${eventName}".`); + } return; } @@ -277,8 +280,18 @@ export function createStreamingBase(config: { config.logger?.info('Closed LaunchDarkly stream connection'); }; - es.onerror = () => { - // Error handling is done by errorFilter. + es.onerror = (err?: HttpErrorResponse) => { + if (stopped) { + return; + } + + if (err && typeof err.status === 'number') { + // This condition will be handled by the error filter. + return; + } + resultQueue.put( + interrupted(errorInfoFromNetworkError(err?.message ?? 'IO Error'), fdv1Fallback), + ); }; es.onopen = () => {