Skip to content

Commit

Permalink
ref(angular): Don't include BrowserApiErrors in bundle (#11294)
Browse files Browse the repository at this point in the history
ref #9508

The `BrowserApiErrors` integration interfers with Angular error handler,
so don't include it in the default integrations.
  • Loading branch information
AbhiPrasad committed Mar 27, 2024
1 parent ad02a79 commit df68e99
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 45 deletions.
2 changes: 1 addition & 1 deletion packages/angular/src/index.ts
Expand Up @@ -2,7 +2,7 @@ export type { ErrorHandlerOptions } from './errorhandler';

export * from '@sentry/browser';

export { init } from './sdk';
export { init, getDefaultIntegrations } from './sdk';
export { createErrorHandler, SentryErrorHandler } from './errorhandler';
export {
browserTracingIntegration,
Expand Down
49 changes: 38 additions & 11 deletions packages/angular/src/sdk.ts
@@ -1,25 +1,52 @@
import { VERSION } from '@angular/core';
import type { BrowserOptions } from '@sentry/browser';
import { getDefaultIntegrations, init as browserInit, setContext } from '@sentry/browser';
import { applySdkMetadata } from '@sentry/core';
import {
breadcrumbsIntegration,
globalHandlersIntegration,
httpContextIntegration,
linkedErrorsIntegration,
} from '@sentry/browser';
import { init as browserInit, setContext } from '@sentry/browser';
import {
applySdkMetadata,
dedupeIntegration,
functionToStringIntegration,
inboundFiltersIntegration,
} from '@sentry/core';
import type { Integration } from '@sentry/types';
import { logger } from '@sentry/utils';

import { IS_DEBUG_BUILD } from './flags';

/**
* Get the default integrations for the Angular SDK.
*/
export function getDefaultIntegrations(): Integration[] {
// Don't include the BrowserApiErrors integration as it interferes with the Angular SDK's `ErrorHandler`:
// BrowserApiErrors would catch certain errors before they reach the `ErrorHandler` and
// thus provide a lower fidelity error than what `SentryErrorHandler`
// (see errorhandler.ts) would provide.
//
// see:
// - https://github.com/getsentry/sentry-javascript/issues/5417#issuecomment-1453407097
// - https://github.com/getsentry/sentry-javascript/issues/2744
return [
inboundFiltersIntegration(),
functionToStringIntegration(),
breadcrumbsIntegration(),
globalHandlersIntegration(),
linkedErrorsIntegration(),
dedupeIntegration(),
httpContextIntegration(),
];
}

/**
* Inits the Angular SDK
*/
export function init(options: BrowserOptions): void {
const opts = {
// Filter out BrowserApiErrors integration as it interferes with our Angular `ErrorHandler`:
// BrowserApiErrors would catch certain errors before they reach the `ErrorHandler` and thus provide a
// lower fidelity error than what `SentryErrorHandler` (see errorhandler.ts) would provide.
// see:
// - https://github.com/getsentry/sentry-javascript/issues/5417#issuecomment-1453407097
// - https://github.com/getsentry/sentry-javascript/issues/2744
defaultIntegrations: getDefaultIntegrations(options).filter(integration => {
return integration.name !== 'BrowserApiErrors';
}),
defaultIntegrations: getDefaultIntegrations(),
...options,
};

Expand Down
43 changes: 10 additions & 33 deletions packages/angular/test/sdk.test.ts
@@ -1,6 +1,6 @@
import * as SentryBrowser from '@sentry/browser';
import { vi } from 'vitest';
import { getDefaultIntegrations, init } from '../src/index';
import { getDefaultIntegrations, init } from '../src/sdk';

describe('init', () => {
it('sets the Angular version (if available) in the global scope', () => {
Expand All @@ -14,39 +14,16 @@ describe('init', () => {
expect(setContextSpy).toHaveBeenCalledWith('angular', { version: 14 });
});

describe('filtering out the `BrowserApiErrors` integration', () => {
const browserInitSpy = vi.spyOn(SentryBrowser, 'init');
it('does not include the BrowserApiErrors integration', () => {
const browserDefaultIntegrationsWithoutBrowserApiErrors = SentryBrowser.getDefaultIntegrations()
.filter(i => i.name !== 'BrowserApiErrors')
.map(i => i.name)
.sort();

beforeEach(() => {
browserInitSpy.mockClear();
});
const angularDefaultIntegrations = getDefaultIntegrations()
.map(i => i.name)
.sort();

it('filters if `defaultIntegrations` is not set', () => {
init({});

expect(browserInitSpy).toHaveBeenCalledTimes(1);

const options = browserInitSpy.mock.calls[0][0] || {};
expect(options.defaultIntegrations).not.toContainEqual(expect.objectContaining({ name: 'BrowserApiErrors' }));
});

it("doesn't filter if `defaultIntegrations` is set to `false`", () => {
init({ defaultIntegrations: false });

expect(browserInitSpy).toHaveBeenCalledTimes(1);

const options = browserInitSpy.mock.calls[0][0] || {};
expect(options.defaultIntegrations).toEqual(false);
});

it("doesn't filter if `defaultIntegrations` is overwritten", () => {
const defaultIntegrations = getDefaultIntegrations({});
init({ defaultIntegrations });

expect(browserInitSpy).toHaveBeenCalledTimes(1);

const options = browserInitSpy.mock.calls[0][0] || {};
expect(options.defaultIntegrations).toEqual(defaultIntegrations);
});
expect(angularDefaultIntegrations).toEqual(browserDefaultIntegrationsWithoutBrowserApiErrors);
});
});
4 changes: 4 additions & 0 deletions packages/browser/src/sdk.ts
Expand Up @@ -32,6 +32,10 @@ import { makeFetchTransport } from './transports/fetch';

/** Get the default integrations for the browser SDK. */
export function getDefaultIntegrations(_options: Options): Integration[] {
/**
* Note: Please make sure this stays in sync with Angular SDK, which re-exports
* `getDefaultIntegrations` but with an adjusted set of integrations.
*/
return [
inboundFiltersIntegration(),
functionToStringIntegration(),
Expand Down

0 comments on commit df68e99

Please sign in to comment.