From 4ce406a0170ed82dfd7bc0da2c6c2876470e1bf6 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 14 Jun 2022 18:31:49 +0200 Subject: [PATCH 1/3] chore(angular): Add Angular version to event contexts Query and send the Angular version to Sentry to help us investigate which Angular versions are used by our users to make support decisions --- packages/angular/src/errorhandler.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index 54449071ee89..0e74320fa154 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -1,5 +1,5 @@ import { HttpErrorResponse } from '@angular/common/http'; -import { ErrorHandler as AngularErrorHandler, Inject, Injectable } from '@angular/core'; +import { ErrorHandler as AngularErrorHandler, Inject, Injectable, VERSION } from '@angular/core'; import * as Sentry from '@sentry/browser'; import { runOutsideAngular } from './zone'; @@ -32,7 +32,6 @@ class SentryErrorHandler implements AngularErrorHandler { ...options, }; } - /** * Method called for every value captured through the ErrorHandler */ @@ -40,7 +39,10 @@ class SentryErrorHandler implements AngularErrorHandler { const extractedError = this._extractError(error) || 'Handled unknown error'; // Capture handled exception and send it to Sentry. - const eventId = runOutsideAngular(() => Sentry.captureException(extractedError)); + const angularVersion = VERSION && VERSION.major ? parseInt(VERSION.major, 10) : 0; + const eventId = runOutsideAngular(() => + Sentry.captureException(extractedError, { contexts: { angular: { version: angularVersion } } }), + ); // When in development mode, log the error to console for immediate feedback. if (this._options.logErrors) { From 9c1efcdea664f2f8eeaff68c638723bf3a5f690c Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Wed, 15 Jun 2022 11:28:57 +0200 Subject: [PATCH 2/3] set version in int() on global scope instead of captureException context --- packages/angular/src/errorhandler.ts | 7 ++----- packages/angular/src/sdk.ts | 17 ++++++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index 0e74320fa154..3bb6ad3c985a 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -1,5 +1,5 @@ import { HttpErrorResponse } from '@angular/common/http'; -import { ErrorHandler as AngularErrorHandler, Inject, Injectable, VERSION } from '@angular/core'; +import { ErrorHandler as AngularErrorHandler, Inject, Injectable } from '@angular/core'; import * as Sentry from '@sentry/browser'; import { runOutsideAngular } from './zone'; @@ -39,10 +39,7 @@ class SentryErrorHandler implements AngularErrorHandler { const extractedError = this._extractError(error) || 'Handled unknown error'; // Capture handled exception and send it to Sentry. - const angularVersion = VERSION && VERSION.major ? parseInt(VERSION.major, 10) : 0; - const eventId = runOutsideAngular(() => - Sentry.captureException(extractedError, { contexts: { angular: { version: angularVersion } } }), - ); + const eventId = runOutsideAngular(() => Sentry.captureException(extractedError)); // When in development mode, log the error to console for immediate feedback. if (this._options.logErrors) { diff --git a/packages/angular/src/sdk.ts b/packages/angular/src/sdk.ts index bcce7c85ccdb..93b6148f2943 100644 --- a/packages/angular/src/sdk.ts +++ b/packages/angular/src/sdk.ts @@ -1,5 +1,5 @@ import { VERSION } from '@angular/core'; -import { BrowserOptions, init as browserInit, SDK_VERSION } from '@sentry/browser'; +import { BrowserOptions, init as browserInit, SDK_VERSION, setContext } from '@sentry/browser'; import { logger } from '@sentry/utils'; import { ANGULAR_MINIMUM_VERSION } from './constants'; @@ -20,20 +20,23 @@ export function init(options: BrowserOptions): void { ], version: SDK_VERSION, }; - checkAngularVersion(); + + checkAndSetAngularVersion(); browserInit(options); } -function checkAngularVersion(): void { - if (VERSION && VERSION.major) { - const major = parseInt(VERSION.major, 10); - if (major < ANGULAR_MINIMUM_VERSION) { +function checkAndSetAngularVersion(): void { + const angularVersion = VERSION && VERSION.major ? parseInt(VERSION.major, 10) : undefined; + + if (angularVersion) { + if (angularVersion < ANGULAR_MINIMUM_VERSION) { IS_DEBUG_BUILD && logger.warn( - `The Sentry SDK does not officially support Angular ${major}.`, + `The Sentry SDK does not officially support Angular ${angularVersion}.`, `This version of the Sentry SDK supports Angular ${ANGULAR_MINIMUM_VERSION} and above.`, 'Please consider upgrading your Angular version or downgrading the Sentry SDK.', ); } + setContext('angular', { version: angularVersion }); } } From 4e50b523cb23c2a70c19cba438d04d68cfb683f3 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Wed, 15 Jun 2022 11:29:22 +0200 Subject: [PATCH 3/3] add test (plus jest config) --- packages/angular/jest.config.js | 6 ++++++ packages/angular/package.json | 5 ++++- packages/angular/src/errorhandler.ts | 1 + packages/angular/test/sdk.test.ts | 16 ++++++++++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 packages/angular/jest.config.js create mode 100644 packages/angular/test/sdk.test.ts diff --git a/packages/angular/jest.config.js b/packages/angular/jest.config.js new file mode 100644 index 000000000000..cd02790794a7 --- /dev/null +++ b/packages/angular/jest.config.js @@ -0,0 +1,6 @@ +const baseConfig = require('../../jest/jest.config.js'); + +module.exports = { + ...baseConfig, + testEnvironment: 'jsdom', +}; diff --git a/packages/angular/package.json b/packages/angular/package.json index ebb30a2ccbe3..1e81abd3a9e5 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -52,7 +52,10 @@ "fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"", "lint": "run-s lint:prettier lint:eslint", "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", - "lint:prettier": "prettier --check \"{src,test,scripts}/**/*.ts\"" + "lint:prettier": "prettier --check \"{src,test,scripts}/**/*.ts\"", + "test": "run-s test:unit", + "test:unit": "jest", + "test:unit:watch": "jest --watch" }, "volta": { "extends": "../../package.json" diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index 3bb6ad3c985a..54449071ee89 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -32,6 +32,7 @@ class SentryErrorHandler implements AngularErrorHandler { ...options, }; } + /** * Method called for every value captured through the ErrorHandler */ diff --git a/packages/angular/test/sdk.test.ts b/packages/angular/test/sdk.test.ts new file mode 100644 index 000000000000..bf5ecabb0ac5 --- /dev/null +++ b/packages/angular/test/sdk.test.ts @@ -0,0 +1,16 @@ +import * as SentryBrowser from '@sentry/browser'; + +import { init } from '../src/sdk'; + +describe('init', () => { + it('sets the Angular version (if available) in the global scope', () => { + const setContextSpy = jest.spyOn(SentryBrowser, 'setContext'); + + init({}); + + // In our case, the Angular version is 10 because that's the version we use for compilation + // (and hence the dependency version of Angular core we installed (see package.json)) + expect(setContextSpy).toHaveBeenCalledTimes(1); + expect(setContextSpy).toHaveBeenCalledWith('angular', { version: 10 }); + }); +});