fix apache/skywalking#7335 (#68)
Co-authored-by: huang <h@xont.me>
diff --git a/CHANGES.md b/CHANGES.md
index f681dd7..c5fc0ac 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -4,6 +4,7 @@
1. Support setting time interval to report segments.
2. Fix segments report only send once
+3. Fix apache/skywalking#7335
## 0.6.0
diff --git a/src/trace/interceptors/fetch.ts b/src/trace/interceptors/fetch.ts
index d1467e3..47d4a39 100644
--- a/src/trace/interceptors/fetch.ts
+++ b/src/trace/interceptors/fetch.ts
@@ -65,10 +65,12 @@
}
}
});
+
+ const collectorURL = new URL(options.collector)
const hasTrace = !(
noTrace ||
(([ReportTypes.ERROR, ReportTypes.ERRORS, ReportTypes.PERF, ReportTypes.SEGMENTS] as string[]).includes(
- url.pathname,
+ url.pathname.replace(new RegExp(`^${collectorURL.pathname}`), ''),
) &&
!options.traceSDKInternal)
);
@@ -92,62 +94,67 @@
args[1].headers['sw8'] = values;
}
- const response = await origFetch(...args);
- const result = response
- .clone()
- .json()
- .then((body: any) => body)
- .catch((err: any) => err);
- if (response.status === 0 || response.status >= 400) {
- const logInfo = {
- uniqueId: uuid(),
- service: options.service,
- serviceVersion: options.serviceVersion,
- pagePath: options.pagePath,
- category: ErrorsCategory.AJAX_ERROR,
- grade: GradeTypeEnum.ERROR,
- errorUrl: response.url || location.href,
- message: `status: ${response.status}; statusText: ${response.statusText};`,
- collector: options.collector,
- stack: 'Fetch: ' + response.statusText,
- };
- new Base().traceInfo(logInfo);
- }
- if (hasTrace) {
- const endTime = new Date().getTime();
- const exitSpan: SpanFields = {
- operationName: options.pagePath,
- startTime: startTime,
- endTime,
- spanId: segment.spans.length,
- spanLayer: SpanLayer,
- spanType: SpanType,
- isError: response.status === 0 || response.status >= 400, // when requests failed, the status is 0
- parentSpanId: segment.spans.length - 1,
- componentId: ComponentId,
- peer: url.host,
- tags: options.detailMode
- ? [
+ let response;
+ try {
+ response = await origFetch(...args);
+
+ return response
+ .clone()
+ .json()
+ .then((body: any) => body)
+ .catch((err: any) => err);
+ } catch (e) {
+ throw e;
+ } finally {
+ if (!response || response.status === 0 || response.status >= 400) {
+ const logInfo = {
+ uniqueId: uuid(),
+ service: options.service,
+ serviceVersion: options.serviceVersion,
+ pagePath: options.pagePath,
+ category: ErrorsCategory.AJAX_ERROR,
+ grade: GradeTypeEnum.ERROR,
+ errorUrl: response?.url || `${url.protocol}//${url.host}${url.pathname}`,
+ message: `status: ${response?.status}; statusText: ${response?.statusText};`,
+ collector: options.collector,
+ stack: 'Fetch: ' + response?.statusText,
+ };
+ new Base().traceInfo(logInfo);
+ }
+ if (hasTrace) {
+ const endTime = new Date().getTime();
+ const exitSpan: SpanFields = {
+ operationName: options.pagePath,
+ startTime: startTime,
+ endTime,
+ spanId: segment.spans.length,
+ spanLayer: SpanLayer,
+ spanType: SpanType,
+ isError: !response || response.status === 0 || response.status >= 400, // when requests failed, the status is 0
+ parentSpanId: segment.spans.length - 1,
+ componentId: ComponentId,
+ peer: url.host,
+ tags: options.detailMode
+ ? [
{
key: 'http.method',
value: args[1].method || 'GET',
},
{
key: 'url',
- value: response.url,
+ value: response?.url || `${url.protocol}//${url.host}${url.pathname}`,
},
]
- : undefined,
- };
- segment = {
- ...segment,
- traceId: traceId,
- traceSegmentId: traceSegmentId,
- };
- segment.spans.push(exitSpan);
- segments.push(segment);
+ : undefined,
+ };
+ segment = {
+ ...segment,
+ traceId: traceId,
+ traceSegmentId: traceSegmentId,
+ };
+ segment.spans.push(exitSpan);
+ segments.push(segment);
+ }
}
-
- return result;
};
}
diff --git a/src/trace/interceptors/xhr.ts b/src/trace/interceptors/xhr.ts
index a4b0119..b829e5b 100644
--- a/src/trace/interceptors/xhr.ts
+++ b/src/trace/interceptors/xhr.ts
@@ -101,9 +101,10 @@
return;
}
+ const collectorURL = new URL(options.collector)
if (
([ReportTypes.ERROR, ReportTypes.ERRORS, ReportTypes.PERF, ReportTypes.SEGMENTS] as string[]).includes(
- url.pathname,
+ url.pathname.replace(new RegExp(`^${collectorURL.pathname}`), ''),
) &&
!options.traceSDKInternal
) {
@@ -138,10 +139,11 @@
const endTime = new Date().getTime();
for (let i = 0; i < segCollector.length; i++) {
if (segCollector[i].event.readyState === ReadyStatus.DONE) {
- let url = {} as URL;
+ let responseURL = {} as URL;
if (segCollector[i].event.status) {
- url = new URL(segCollector[i].event.responseURL);
+ responseURL = new URL(segCollector[i].event.responseURL);
}
+
const exitSpan: SpanFields = {
operationName: options.pagePath,
startTime: segCollector[i].startTime,
@@ -152,7 +154,7 @@
isError: event.detail.status === 0 || event.detail.status >= 400, // when requests failed, the status is 0
parentSpanId: segment.spans.length - 1,
componentId: ComponentId,
- peer: url.host,
+ peer: responseURL.host,
tags: options.detailMode
? [
{
@@ -161,7 +163,7 @@
},
{
key: 'url',
- value: segCollector[i].event.responseURL,
+ value: segCollector[i].event.responseURL || `${url.protocol}//${url.host}${url.pathname}`,
},
]
: undefined,