Skip to content

Commit d3b4c9f

Browse files
committed
feat: network plugin - handle empty performance entry
1 parent 6a46d81 commit d3b4c9f

File tree

1 file changed

+92
-45
lines changed
  • packages/plugins/rrweb-plugin-network-record/src

1 file changed

+92
-45
lines changed

packages/plugins/rrweb-plugin-network-record/src/index.ts

+92-45
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
11
import type { listenerHandler, RecordPlugin, IWindow } from '@rrweb/types';
22
import { patch } from '@rrweb/utils';
33

4-
function findLast<T>(
5-
array: Array<T>,
6-
predicate: (value: T) => boolean,
7-
): T | undefined {
8-
const length = array.length;
9-
for (let i = length - 1; i >= 0; i -= 1) {
10-
if (predicate(array[i])) {
11-
return array[i];
12-
}
13-
}
14-
}
15-
164
export type InitiatorType =
175
| 'audio'
186
| 'beacon'
@@ -89,12 +77,17 @@ type Body =
8977
| ReadableStream<Uint8Array>
9078
| null;
9179

92-
type NetworkRequest = Omit<PerformanceEntry, 'toJSON'> & {
80+
type NetworkRequest = Omit<
81+
PerformanceEntry,
82+
'toJSON' | 'startTime' | 'endTime' | 'duration' | 'entryType'
83+
> & {
9384
method?: string;
9485
initiatorType?: InitiatorType;
9586
status?: number;
9687
startTime?: number;
9788
endTime?: number;
89+
duration?: number;
90+
entryType?: string;
9891
requestHeaders?: Headers;
9992
requestBody?: Body;
10093
responseHeaders?: Headers;
@@ -345,22 +338,23 @@ function initXhrObserver(
345338
before,
346339
)
347340
.then((entry) => {
348-
if (!entry) return;
349-
const request: NetworkRequest = {
350-
method: req.method,
351-
initiatorType: entry.initiatorType as InitiatorType,
352-
duration: entry.duration,
353-
entryType: entry.entryType,
354-
name: entry.name,
355-
status: xhr.status,
356-
startTime: Math.round(entry.startTime),
357-
endTime: Math.round(entry.responseEnd),
358-
requestHeaders: networkRequest.requestHeaders,
359-
requestBody: networkRequest.requestBody,
360-
responseHeaders: networkRequest.responseHeaders,
361-
responseBody: networkRequest.responseBody,
362-
};
363-
cb({ requests: [request] });
341+
if (!entry) {
342+
// https://github.com/rrweb-io/rrweb/pull/1105#issuecomment-1953808336
343+
const requests = prepareRequestWithoutPerformance(
344+
req,
345+
networkRequest,
346+
);
347+
cb({ requests });
348+
return;
349+
}
350+
351+
const requests = prepareRequest(
352+
entry,
353+
req.method,
354+
xhr.status,
355+
networkRequest,
356+
);
357+
cb({ requests });
364358
})
365359
.catch(() => {
366360
//
@@ -446,22 +440,23 @@ function initFetchObserver(
446440
} finally {
447441
getRequestPerformanceEntry(win, 'fetch', req.url, after, before)
448442
.then((entry) => {
449-
if (!entry) return;
450-
const request: NetworkRequest = {
451-
method: req.method,
452-
initiatorType: entry.initiatorType as InitiatorType,
453-
duration: entry.duration,
454-
entryType: entry.entryType,
455-
name: entry.name,
456-
status: res?.status,
457-
startTime: Math.round(entry.startTime),
458-
endTime: Math.round(entry.responseEnd),
459-
requestHeaders: networkRequest.requestHeaders,
460-
requestBody: networkRequest.requestBody,
461-
responseHeaders: networkRequest.responseHeaders,
462-
responseBody: networkRequest.responseBody,
463-
};
464-
cb({ requests: [request] });
443+
if (!entry) {
444+
// https://github.com/rrweb-io/rrweb/pull/1105#issuecomment-1953808336
445+
const requests = prepareRequestWithoutPerformance(
446+
req,
447+
networkRequest,
448+
);
449+
cb({ requests });
450+
return;
451+
}
452+
453+
const requests = prepareRequest(
454+
entry,
455+
req.method,
456+
res?.status,
457+
networkRequest,
458+
);
459+
cb({ requests });
465460
})
466461
.catch(() => {
467462
//
@@ -509,6 +504,58 @@ function initNetworkObserver(
509504
};
510505
}
511506

507+
function prepareRequest(
508+
entry: PerformanceResourceTiming,
509+
method: string | undefined,
510+
status: number | undefined,
511+
networkRequest: Partial<NetworkRequest>,
512+
): NetworkRequest[] {
513+
const request: NetworkRequest = {
514+
method,
515+
initiatorType: entry.initiatorType as InitiatorType,
516+
duration: entry.duration,
517+
entryType: entry.entryType,
518+
name: entry.name,
519+
status,
520+
startTime: Math.round(entry.startTime),
521+
endTime: Math.round(entry.responseEnd),
522+
requestHeaders: networkRequest.requestHeaders,
523+
requestBody: networkRequest.requestBody,
524+
responseHeaders: networkRequest.responseHeaders,
525+
responseBody: networkRequest.responseBody,
526+
};
527+
528+
return [request];
529+
}
530+
531+
function prepareRequestWithoutPerformance(
532+
req: Request,
533+
networkRequest: Partial<NetworkRequest>,
534+
): NetworkRequest[] {
535+
const request: NetworkRequest = {
536+
name: req.url,
537+
method: req.method,
538+
requestHeaders: networkRequest.requestHeaders,
539+
requestBody: networkRequest.requestBody,
540+
responseHeaders: networkRequest.responseHeaders,
541+
responseBody: networkRequest.responseBody,
542+
};
543+
544+
return [request];
545+
}
546+
547+
function findLast<T>(
548+
array: Array<T>,
549+
predicate: (value: T) => boolean,
550+
): T | undefined {
551+
const length = array.length;
552+
for (let i = length - 1; i >= 0; i -= 1) {
553+
if (predicate(array[i])) {
554+
return array[i];
555+
}
556+
}
557+
}
558+
512559
export const PLUGIN_NAME = 'rrweb/network@1';
513560

514561
export const getRecordNetworkPlugin: (

0 commit comments

Comments
 (0)