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,