Skip to content

Commit 6b1285c

Browse files
mhennochdyladanvmarchaud
authored
fix(plugin-fetch): check if PerformanceObserver exists (#1662)
Co-authored-by: Daniel Dyla <[email protected]> Co-authored-by: Valentin Marchaud <[email protected]>
1 parent 08d5229 commit 6b1285c

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

packages/opentelemetry-instrumentation-fetch/src/fetch.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ export class FetchInstrumentation extends InstrumentationBase<
198198
): void {
199199
let resources: PerformanceResourceTiming[] = resourcesObserver.entries;
200200
if (!resources.length) {
201+
if (!performance.getEntriesByType) {
202+
return;
203+
}
201204
// fallback - either Observer is not available or it took longer
202205
// then OBSERVER_WAIT_TIME_MS and observer didn't collect enough
203206
// information
@@ -249,7 +252,8 @@ export class FetchInstrumentation extends InstrumentationBase<
249252
response: FetchResponse
250253
) {
251254
const endTime = core.hrTime();
252-
spanData.observer.disconnect();
255+
spanData.observer?.disconnect();
256+
253257
this._addFinalSpanAttributes(span, response);
254258

255259
setTimeout(() => {
@@ -348,6 +352,11 @@ export class FetchInstrumentation extends InstrumentationBase<
348352
private _prepareSpanData(spanUrl: string): SpanData {
349353
const startTime = core.hrTime();
350354
const entries: PerformanceResourceTiming[] = [];
355+
356+
if (typeof window.PerformanceObserver === 'undefined') {
357+
return { entries, startTime, spanUrl };
358+
}
359+
351360
const observer: PerformanceObserver = new PerformanceObserver(list => {
352361
const entries = list.getEntries() as PerformanceResourceTiming[];
353362
entries.forEach(entry => {

packages/opentelemetry-instrumentation-fetch/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export interface FetchError {
3939
*/
4040
export interface SpanData {
4141
entries: PerformanceResourceTiming[];
42-
observer: PerformanceObserver;
42+
observer?: PerformanceObserver;
4343
spanUrl: string;
4444
startTime: api.HrTime;
4545
}

packages/opentelemetry-instrumentation-fetch/test/fetch.test.ts

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ describe('fetch', () => {
121121
done: any,
122122
fileUrl: string,
123123
config: FetchInstrumentationConfig,
124-
method?: string
124+
method?: string,
125+
disablePerfObserver?: boolean,
126+
disableGetEntries?: boolean
125127
) => {
126128
sandbox = sinon.createSandbox();
127129
sandbox.useFakeTimers();
@@ -165,8 +167,16 @@ describe('fetch', () => {
165167
})
166168
);
167169

168-
const spyEntries = sandbox.stub(performance, 'getEntriesByType');
169-
spyEntries.withArgs('resource').returns(resources);
170+
if (disablePerfObserver) {
171+
sandbox.stub(window, 'PerformanceObserver').value(undefined);
172+
}
173+
if (disableGetEntries) {
174+
sandbox.stub(performance, 'getEntriesByType').value(undefined);
175+
} else {
176+
const spyEntries = sandbox.stub(performance, 'getEntriesByType');
177+
spyEntries.withArgs('resource').returns(resources);
178+
}
179+
170180
fetchInstrumentation = new FetchInstrumentation(config);
171181
webTracerProviderWithZone = new WebTracerProvider({
172182
logLevel: core.LogLevel.ERROR,
@@ -586,4 +596,43 @@ describe('fetch', () => {
586596
);
587597
});
588598
});
599+
600+
describe('when PerformanceObserver is undefined', () => {
601+
beforeEach(done => {
602+
prepareData(done, url, {}, undefined, true, false);
603+
});
604+
605+
afterEach(() => {
606+
clearData();
607+
});
608+
609+
it('should still create spans', () => {
610+
assert.strictEqual(
611+
exportSpy.args.length,
612+
2,
613+
`Wrong number of spans: ${exportSpy.args.length}`
614+
);
615+
});
616+
});
617+
618+
describe('when PerformanceObserver and performance.getEntriesByType are undefined', () => {
619+
beforeEach(done => {
620+
prepareData(done, url, {}, undefined, true, true);
621+
});
622+
afterEach(() => {
623+
clearData();
624+
});
625+
it('should capture fetch without preflight', () => {
626+
assert.strictEqual(
627+
exportSpy.args.length,
628+
1,
629+
`Wrong number of spans: ${exportSpy.args.length}`
630+
);
631+
assert.strictEqual(
632+
exportSpy.args[0][0][0].name,
633+
'HTTP GET',
634+
'wrong span captured'
635+
);
636+
});
637+
});
589638
});

0 commit comments

Comments
 (0)