Skip to content

Commit 451caaf

Browse files
authored
fix(instrumentation-browser-navigation): use 'declare' to avoid JS class field initialization surprise (open-telemetry#3326)
Before this change these class fields were being set to undefined after the super() call, which blows away values set in the .enable() called by the super constructor. This also reverts the following change that was attempting to work around test failures: "fix(instrumentation-browser-navigation): improve test stability with … (open-telemetry#3323)" This also adds a guard on .enable() being called multiple times because it isn't idempotent. Fixes: open-telemetry#3310
1 parent bb0334b commit 451caaf

File tree

2 files changed

+112
-186
lines changed

2 files changed

+112
-186
lines changed

packages/instrumentation-browser-navigation/src/instrumentation.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,18 @@ export const ATTR_BROWSER_NAVIGATION_TYPE = 'browser.navigation.type';
4040
export class BrowserNavigationInstrumentation extends InstrumentationBase<BrowserNavigationInstrumentationConfig> {
4141
applyCustomLogRecordData: ApplyCustomLogRecordDataFunction | undefined =
4242
undefined;
43-
sanitizeUrl?: SanitizeUrlFunction; // No default sanitization
44-
private _onLoadHandler?: () => void;
45-
private _onPopStateHandler?: (ev: PopStateEvent) => void;
46-
private _onNavigateHandler?: (ev: Event) => void;
43+
declare sanitizeUrl?: SanitizeUrlFunction; // No default sanitization
44+
declare private _onLoadHandler?: () => void;
45+
declare private _onPopStateHandler?: (ev: PopStateEvent) => void;
46+
declare private _onNavigateHandler?: (ev: Event) => void;
4747
private _lastUrl: string = location.href;
4848
private _hasProcessedInitialLoad: boolean = false;
4949

50+
// Note: Intentionally *not* using `_enabled` as the field name to avoid
51+
// any possible confusion with the `_enabled` field used on the *Node.js*
52+
// InstrumentationBase class.
53+
declare private _isEnabled: boolean;
54+
5055
/**
5156
*
5257
* @param config
@@ -133,8 +138,7 @@ export class BrowserNavigationInstrumentation extends InstrumentationBase<Browse
133138
// Check if document has already loaded completely
134139
if (document.readyState === 'complete' && !this._hasProcessedInitialLoad) {
135140
this._hasProcessedInitialLoad = true;
136-
// Use setTimeout to allow tests to reset exporter before this fires
137-
setTimeout(() => this._onHardNavigation(), 0);
141+
this._onHardNavigation();
138142
return;
139143
}
140144

@@ -155,6 +159,11 @@ export class BrowserNavigationInstrumentation extends InstrumentationBase<Browse
155159
* implements enable function
156160
*/
157161
override enable() {
162+
if (this._isEnabled) {
163+
return;
164+
}
165+
this._isEnabled = true;
166+
158167
const cfg = this.getConfig() as BrowserNavigationInstrumentationConfig;
159168
const useNavigationApiIfAvailable = !!cfg.useNavigationApiIfAvailable;
160169
const navigationApi =
@@ -200,6 +209,11 @@ export class BrowserNavigationInstrumentation extends InstrumentationBase<Browse
200209
* implements disable function
201210
*/
202211
override disable() {
212+
if (!this._isEnabled) {
213+
return;
214+
}
215+
this._isEnabled = false;
216+
203217
this._unpatchHistoryApi();
204218
if (this._onLoadHandler) {
205219
document.removeEventListener('DOMContentLoaded', this._onLoadHandler);
@@ -243,8 +257,10 @@ export class BrowserNavigationInstrumentation extends InstrumentationBase<Browse
243257
}
244258

245259
private _patchHistoryApi(): void {
246-
// unpatching here disables other instrumentation that use the same api to wrap history, commenting it out
247-
// this._unpatchHistoryApi();
260+
// Unpatching here disables other instrumentation that use the same api to
261+
// wrap history, commenting it out.
262+
// this._unpatchHistoryApi();
263+
// TODO: For example, instrumentation-user-interaction also patches `history`. Do the two instrumentations work at the same time?
248264
this._wrap(
249265
history,
250266
'replaceState',

0 commit comments

Comments
 (0)