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/09 12:57:06 UTC
[skywalking-client-js] 24/32: 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;