You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2020/01/08 05:43:42 UTC

[skywalking-client-js] 24/29: feat: support ajax and promise error for trace

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-client-js.git

commit 3c0ee0bb3bb03d73e7907c809e2de87d5230870e
Author: Qiuxia Fan <fi...@outlook.com>
AuthorDate: Wed Jan 8 11:15:27 2020 +0800

    feat: support ajax and promise error for trace
---
 src/errors/ajax.ts                     | 66 ++++++++++++++++++++++++++++++++++
 src/{types.d.ts => errors/index.ts}    | 19 ++++------
 src/errors/{jsErrors.ts => js.ts}      |  7 ++--
 src/errors/{jsErrors.ts => promise.ts} | 43 ++++++++++++----------
 src/monitor.ts                         | 35 ++++++++++--------
 src/services/base.ts                   |  2 +-
 src/services/report.ts                 |  5 +--
 src/services/types.d.ts                |  6 ++--
 src/types.d.ts                         |  6 ++--
 9 files changed, 129 insertions(+), 60 deletions(-)

diff --git a/src/errors/ajax.ts b/src/errors/ajax.ts
new file mode 100644
index 0000000..9727339
--- /dev/null
+++ b/src/errors/ajax.ts
@@ -0,0 +1,66 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Base from '../services/base';
+import { GradeTypeEnum, ErrorsCategory } from '../services/constant';
+
+class AjaxErrors extends Base {
+  public handleError(options: {reportUrl: string}) {
+    if (!window.XMLHttpRequest) {
+      return;
+    }
+    const xhrSend = XMLHttpRequest.prototype.send;
+    const xhrEvent = (event: any) => {
+      try {
+        if (event && event.currentTarget && event.currentTarget.status !== 200) {
+          this.logInfo = {
+            reportUrl: options.reportUrl,
+            category: ErrorsCategory.AJAX_ERROR,
+            grade: GradeTypeEnum.ERROR,
+            errorUrl: event.target.responseURL,
+            message: event.target.response,
+            errorInfo: {
+              status: event.target.status,
+              statusText: event.target.statusText,
+            },
+          };
+          this.traceInfo();
+        }
+      } catch (error) {
+        console.log(error);
+      }
+    };
+    XMLHttpRequest.prototype.send = function() {
+      if (this.addEventListener) {
+        this.addEventListener('error', xhrEvent);
+        this.addEventListener('load', xhrEvent);
+        this.addEventListener('abort', xhrEvent);
+      } else {
+        const tempStateChange = this.onreadystatechange;
+        this.onreadystatechange = function(event: any) {
+          tempStateChange.apply(this, arguments);
+          if (this.readyState === 4) {
+            xhrEvent(event);
+          }
+        };
+      }
+      return xhrSend.apply(this, arguments);
+    };
+  }
+}
+
+export default new AjaxErrors();
diff --git a/src/types.d.ts b/src/errors/index.ts
similarity index 73%
copy from src/types.d.ts
copy to src/errors/index.ts
index b7f6058..b213fd0 100644
--- a/src/types.d.ts
+++ b/src/errors/index.ts
@@ -14,17 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-export interface TClientMonitor {
-  reportUrl: string;
-  modulesName?: string;
-}
+import JSErrors from './js';
+import PromiseErrors from './promise';
+import AjaxErrors from './ajax';
 
-export interface TErrorsType {
-  jsErrors: boolean;
-  promiseErrors: boolean;
-  consoleErrors: boolean;
-  vueErrors: boolean;
-  reactErrors: boolean;
-  ajaxErrors: boolean;
-  resourceErrors: boolean;
-}
+export {
+  JSErrors, PromiseErrors, AjaxErrors,
+};
diff --git a/src/errors/jsErrors.ts b/src/errors/js.ts
similarity index 86%
copy from src/errors/jsErrors.ts
copy to src/errors/js.ts
index cb7756d..121d19f 100644
--- a/src/errors/jsErrors.ts
+++ b/src/errors/js.ts
@@ -15,11 +15,10 @@
  * limitations under the License.
  */
 
-import BaseMonitor from '../services/base';
-import { GradeTypeEnum } from '../services/constant';
-import { ErrorsCategory } from '../services/constant';
+import Base from '../services/base';
+import { GradeTypeEnum, ErrorsCategory } from '../services/constant';
 
-class JSErrors extends BaseMonitor {
+class JSErrors extends Base {
   public handleErrors(options: {reportUrl: string}) {
     window.onerror = (message, url, line, col, error) => {
       this.logInfo = {
diff --git a/src/errors/jsErrors.ts b/src/errors/promise.ts
similarity index 52%
rename from src/errors/jsErrors.ts
rename to src/errors/promise.ts
index cb7756d..e8ae5c7 100644
--- a/src/errors/jsErrors.ts
+++ b/src/errors/promise.ts
@@ -15,25 +15,32 @@
  * limitations under the License.
  */
 
-import BaseMonitor from '../services/base';
-import { GradeTypeEnum } from '../services/constant';
-import { ErrorsCategory } from '../services/constant';
+import Base from '../services/base';
+import { GradeTypeEnum, ErrorsCategory } from '../services/constant';
 
-class JSErrors extends BaseMonitor {
+class PromiseErrors extends Base {
   public handleErrors(options: {reportUrl: string}) {
-    window.onerror = (message, url, line, col, error) => {
-      this.logInfo = {
-        reportUrl: options.reportUrl,
-        category: ErrorsCategory.JS_ERROR,
-        grade: GradeTypeEnum.ERROR,
-        errorUrl: url,
-        line,
-        col,
-        errorInfo: error,
-        message,
-      };
-      this.traceInfo();
-    };
+    window.addEventListener('unhandledrejection', (event) => {
+      try {
+        let url = '';
+        if (!event || !event.reason) {
+          return;
+        }
+        if (event.reason.config && event.reason.config.url) {
+          url = event.reason.config.url;
+        }
+        this.logInfo = {
+          reportUrl: options.reportUrl,
+          category: ErrorsCategory.PROMISE_ERROR,
+          grade: GradeTypeEnum.ERROR,
+          errorUrl: url,
+          message: event.reason,
+        };
+        this.traceInfo();
+      } catch (error) {
+        console.log(error);
+      }
+    });
   }
 }
-export default new JSErrors();
+export default new PromiseErrors();
diff --git a/src/monitor.ts b/src/monitor.ts
index b24faf0..582f1b4 100644
--- a/src/monitor.ts
+++ b/src/monitor.ts
@@ -14,11 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import JSErrors from './errors/jsErrors';
-import { TClientMonitor, TErrorsType } from './types';
+
+import { CustomOptionsType } from './types';
+import { JSErrors, PromiseErrors, AjaxErrors } from './errors/index';
 
 const ClientMonitor = {
-  errorTypes: {
+  customOptions: {
     jsErrors: true,
     promiseErrors: true,
     consoleErrors: false,
@@ -26,22 +27,26 @@ const ClientMonitor = {
     reactErrors: false,
     ajaxErrors: true,
     resourceErrors: true,
-  } as TErrorsType,
+  } as CustomOptionsType,
+
+  register(options: CustomOptionsType) {
+    const reportUrl = options.reportUrl;
 
-  register(options: TClientMonitor & TErrorsType) {
-    this.errorTypes = options;
-    if (this.errorTypes.jsErrors) {
-      this.errorTypes.jsErrors = options.jsErrors;
-      JSErrors.handleErrors({reportUrl: options.reportUrl});
+    this.customOptions = options;
+    if (this.customOptions.jsErrors) {
+      this.customOptions.jsErrors = options.jsErrors;
+      JSErrors.handleErrors({reportUrl});
     }
-    if (this.errorTypes.promiseErrors) {
-      this.errorTypes.promiseErrors = options.promiseErrors || this.errorTypes.promiseErrors;
+    if (this.customOptions.promiseErrors) {
+      this.customOptions.promiseErrors = options.promiseErrors || this.customOptions.promiseErrors;
+      PromiseErrors.handleErrors({reportUrl});
     }
-    if (this.errorTypes.resourceErrors) {
-      this.errorTypes.resourceErrors = options.resourceErrors;
+    if (this.customOptions.resourceErrors) {
+      this.customOptions.resourceErrors = options.resourceErrors;
     }
-    if (this.errorTypes.ajaxErrors) {
-      this.errorTypes.ajaxErrors = options.ajaxErrors || this.errorTypes.ajaxErrors;
+    if (this.customOptions.ajaxErrors) {
+      this.customOptions.ajaxErrors = options.ajaxErrors || this.customOptions.ajaxErrors;
+      AjaxErrors.handleError({reportUrl});
     }
   },
 };
diff --git a/src/services/base.ts b/src/services/base.ts
index 5437912..a8b0c6f 100644
--- a/src/services/base.ts
+++ b/src/services/base.ts
@@ -18,7 +18,7 @@ import Task from './task';
 import { ErrorsCategory, GradeTypeEnum } from './constant';
 import { errorInfoFeilds } from './types';
 
-export default class BaseMonitor {
+export default class Base {
   public logInfo: errorInfoFeilds & {reportUrl: string} = {
     category: ErrorsCategory.UNKNOW_ERROR,
     grade: GradeTypeEnum.INFO,
diff --git a/src/services/report.ts b/src/services/report.ts
index a6e080a..81b4a70 100644
--- a/src/services/report.ts
+++ b/src/services/report.ts
@@ -27,14 +27,15 @@ class Report {
     if (!this.checkUrl(this.url)) {
       return;
     }
+    console.log(data);
+    delete data.reportUrl;
     try {
       const xhr = new XMLHttpRequest();
       xhr.open('POST', this.url, true);
       xhr.setRequestHeader('Content-Type', 'application/json');
-      console.log(data);
       xhr.send(JSON.stringify(data));
     } catch (error) {
-    //   console.log(error);
+      console.log(error);
     }
   }
 
diff --git a/src/services/types.d.ts b/src/services/types.d.ts
index d296077..b027d5e 100644
--- a/src/services/types.d.ts
+++ b/src/services/types.d.ts
@@ -38,7 +38,7 @@ export interface errorInfoFeilds {
   grade: string;
   message: any;
   errorUrl: string;
-  line: number; 
-  col: number;
-  errorInfo: any;
+  line?: number; 
+  col?: number;
+  errorInfo?: any;
 }
diff --git a/src/types.d.ts b/src/types.d.ts
index b7f6058..0d6b2c3 100644
--- a/src/types.d.ts
+++ b/src/types.d.ts
@@ -14,12 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-export interface TClientMonitor {
+
+export interface CustomOptionsType {
   reportUrl: string;
   modulesName?: string;
-}
-
-export interface TErrorsType {
   jsErrors: boolean;
   promiseErrors: boolean;
   consoleErrors: boolean;