sobey-monitor-sdk 1.1.17 → 1.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +107 -23
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +22 -0
- package/dist/index.esm.js +107 -23
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +107 -23
- package/dist/index.umd.js.map +1 -1
- package/dist/types/index.d.ts +22 -0
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -110,6 +110,21 @@ interface ErrorMonitorConfig {
|
|
|
110
110
|
* 例如: [404, 500, 502, 503, 504]
|
|
111
111
|
*/
|
|
112
112
|
httpErrorStatusCodes?: number[];
|
|
113
|
+
/**
|
|
114
|
+
* 是否上报网络错误(请求失败,无法连接到服务器)
|
|
115
|
+
* 默认值: false
|
|
116
|
+
*/
|
|
117
|
+
reportNetworkError?: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* 是否上报请求超时错误
|
|
120
|
+
* 默认值: false
|
|
121
|
+
*/
|
|
122
|
+
reportTimeoutError?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* 是否上报请求取消错误(用户主动取消或页面切换导致的取消)
|
|
125
|
+
* 默认值: false
|
|
126
|
+
*/
|
|
127
|
+
reportAbortError?: boolean;
|
|
113
128
|
}
|
|
114
129
|
/**
|
|
115
130
|
* 性能监控配置
|
|
@@ -217,6 +232,13 @@ interface HttpInfo {
|
|
|
217
232
|
requestBody?: string;
|
|
218
233
|
/** 响应体 */
|
|
219
234
|
responseBody?: string;
|
|
235
|
+
/**
|
|
236
|
+
* 错误类型(当 status 为 0 时)
|
|
237
|
+
* - 'timeout': 请求超时
|
|
238
|
+
* - 'abort': 请求被取消
|
|
239
|
+
* - 'network': 网络错误
|
|
240
|
+
*/
|
|
241
|
+
errorType?: 'timeout' | 'abort' | 'network';
|
|
220
242
|
}
|
|
221
243
|
/**
|
|
222
244
|
* 性能数据
|
package/dist/index.esm.js
CHANGED
|
@@ -423,11 +423,11 @@ if (typeof window !== 'undefined') {
|
|
|
423
423
|
});
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
+
var version = "1.1.19";
|
|
427
|
+
|
|
426
428
|
/**
|
|
427
429
|
* 数据上报管理
|
|
428
430
|
*/
|
|
429
|
-
// SDK 版本
|
|
430
|
-
const SDK_VERSION$1 = '1.0.0';
|
|
431
431
|
/**
|
|
432
432
|
* 上报器类
|
|
433
433
|
*/
|
|
@@ -564,7 +564,7 @@ class Reporter {
|
|
|
564
564
|
pageUrl: getPageUrl(),
|
|
565
565
|
timestamp: Date.now(),
|
|
566
566
|
userAgent: getUserAgent(),
|
|
567
|
-
sdkVersion: cfg.version ||
|
|
567
|
+
sdkVersion: cfg.version || version,
|
|
568
568
|
};
|
|
569
569
|
}
|
|
570
570
|
/**
|
|
@@ -839,21 +839,43 @@ function shouldReportHttpError(status) {
|
|
|
839
839
|
// 获取配置的状态码列表
|
|
840
840
|
if (!config.isInitialized()) {
|
|
841
841
|
// 配置未初始化时,不上报
|
|
842
|
+
console.log(`[Monitor] shouldReportHttpError: config not initialized, status=${status}, returning false`);
|
|
842
843
|
return false;
|
|
843
844
|
}
|
|
844
845
|
const cfg = config.get();
|
|
845
846
|
const httpErrorStatusCodes = cfg.error?.httpErrorStatusCodes;
|
|
846
847
|
// 如果未配置状态码列表或为空数组,则不上报任何HTTP错误
|
|
847
848
|
if (!httpErrorStatusCodes || httpErrorStatusCodes.length === 0) {
|
|
849
|
+
console.log(`[Monitor] shouldReportHttpError: no httpErrorStatusCodes configured, status=${status}, returning false`);
|
|
848
850
|
return false;
|
|
849
851
|
}
|
|
850
852
|
// 只检查状态码是否在配置的列表中
|
|
851
853
|
const shouldReport = httpErrorStatusCodes.includes(status);
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
}
|
|
854
|
+
// 临时强制输出调试日志
|
|
855
|
+
console.log(`[Monitor] HTTP status ${status} shouldReport: ${shouldReport}, configured codes:`, httpErrorStatusCodes);
|
|
855
856
|
return shouldReport;
|
|
856
857
|
}
|
|
858
|
+
/**
|
|
859
|
+
* 根据错误类型判断是否应该上报网络类错误(status = 0)
|
|
860
|
+
* @param errorType 错误类型:'timeout' | 'abort' | 'network'
|
|
861
|
+
* @returns 是否应该上报
|
|
862
|
+
*/
|
|
863
|
+
function shouldReportNetworkTypeError(errorType) {
|
|
864
|
+
if (!config.isInitialized()) {
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
867
|
+
const cfg = config.get();
|
|
868
|
+
const errorConfig = cfg.error;
|
|
869
|
+
switch (errorType) {
|
|
870
|
+
case 'timeout':
|
|
871
|
+
return errorConfig?.reportTimeoutError === true;
|
|
872
|
+
case 'abort':
|
|
873
|
+
return errorConfig?.reportAbortError === true;
|
|
874
|
+
case 'network':
|
|
875
|
+
default:
|
|
876
|
+
return errorConfig?.reportNetworkError === true;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
857
879
|
/**
|
|
858
880
|
* 获取嵌套对象的字段值
|
|
859
881
|
* @param obj 对象
|
|
@@ -972,7 +994,20 @@ function interceptXHR() {
|
|
|
972
994
|
if (monitorData) {
|
|
973
995
|
monitorData.startTime = Date.now();
|
|
974
996
|
monitorData.requestBody = typeof body === 'string' ? body : undefined;
|
|
997
|
+
monitorData.errorType = undefined; // 初始化错误类型
|
|
975
998
|
}
|
|
999
|
+
// 监听超时事件
|
|
1000
|
+
this.addEventListener('timeout', function () {
|
|
1001
|
+
if (monitorData) {
|
|
1002
|
+
monitorData.errorType = 'timeout';
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1005
|
+
// 监听取消事件
|
|
1006
|
+
this.addEventListener('abort', function () {
|
|
1007
|
+
if (monitorData) {
|
|
1008
|
+
monitorData.errorType = 'abort';
|
|
1009
|
+
}
|
|
1010
|
+
});
|
|
976
1011
|
this.addEventListener('loadend', function () {
|
|
977
1012
|
if (!monitorData)
|
|
978
1013
|
return;
|
|
@@ -986,6 +1021,11 @@ function interceptXHR() {
|
|
|
986
1021
|
// 其他异常情况(0-网络错误、4xx-客户端错误、5xx-服务端错误)根据配置控制
|
|
987
1022
|
const isError = status === 0 || status < 200 || status >= 400;
|
|
988
1023
|
const shouldRecord = isRedirect || recordMode === 'all' || (recordMode === 'error' && isError);
|
|
1024
|
+
// 确定错误类型
|
|
1025
|
+
let errorType;
|
|
1026
|
+
if (status === 0) {
|
|
1027
|
+
errorType = monitorData.errorType || 'network';
|
|
1028
|
+
}
|
|
989
1029
|
if (shouldRecord) {
|
|
990
1030
|
context.addBreadcrumb({
|
|
991
1031
|
type: 'request',
|
|
@@ -995,12 +1035,22 @@ function interceptXHR() {
|
|
|
995
1035
|
url: monitorData.url,
|
|
996
1036
|
status,
|
|
997
1037
|
duration,
|
|
1038
|
+
errorType,
|
|
998
1039
|
},
|
|
999
1040
|
});
|
|
1000
1041
|
}
|
|
1001
1042
|
const responseBody = this.responseText?.substring(0, 1000);
|
|
1002
|
-
// HTTP
|
|
1003
|
-
|
|
1043
|
+
// HTTP 错误上报逻辑
|
|
1044
|
+
let shouldReport = false;
|
|
1045
|
+
if (status === 0) {
|
|
1046
|
+
// status=0 使用独立的网络错误配置
|
|
1047
|
+
shouldReport = shouldReportNetworkTypeError(errorType);
|
|
1048
|
+
}
|
|
1049
|
+
else {
|
|
1050
|
+
// 其他状态码使用 httpErrorStatusCodes 配置
|
|
1051
|
+
shouldReport = shouldReportHttpError(status);
|
|
1052
|
+
}
|
|
1053
|
+
if (shouldReport) {
|
|
1004
1054
|
reportHttpError({
|
|
1005
1055
|
method: monitorData.method,
|
|
1006
1056
|
url: monitorData.url,
|
|
@@ -1008,6 +1058,7 @@ function interceptXHR() {
|
|
|
1008
1058
|
duration,
|
|
1009
1059
|
requestBody: monitorData.requestBody,
|
|
1010
1060
|
responseBody,
|
|
1061
|
+
errorType,
|
|
1011
1062
|
});
|
|
1012
1063
|
}
|
|
1013
1064
|
else if (status >= 200 && status < 300 && detectBusinessError(responseBody)) {
|
|
@@ -1100,6 +1151,22 @@ function interceptFetch() {
|
|
|
1100
1151
|
}
|
|
1101
1152
|
catch (error) {
|
|
1102
1153
|
const duration = Date.now() - startTime;
|
|
1154
|
+
const err = error;
|
|
1155
|
+
// 判断错误类型
|
|
1156
|
+
// AbortError 表示请求被取消(可能是手动取消或超时)
|
|
1157
|
+
// 注意:fetch 的超时通常也是通过 AbortController 实现的,所以无法区分超时和手动取消
|
|
1158
|
+
// 这里将 AbortError 统一标记为 'abort',如果需要区分超时,建议使用 XHR 或检查 error.message
|
|
1159
|
+
let errorType = 'network';
|
|
1160
|
+
if (err.name === 'AbortError') {
|
|
1161
|
+
// 尝试通过错误消息区分超时和取消
|
|
1162
|
+
// 一些超时实现会在 message 中包含 'timeout'
|
|
1163
|
+
if (err.message?.toLowerCase().includes('timeout')) {
|
|
1164
|
+
errorType = 'timeout';
|
|
1165
|
+
}
|
|
1166
|
+
else {
|
|
1167
|
+
errorType = 'abort';
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1103
1170
|
// 网络错误时根据配置决定是否添加到面包屑
|
|
1104
1171
|
const cfg = config.isInitialized() ? config.get() : null;
|
|
1105
1172
|
const recordMode = cfg?.behavior?.recordRequestBreadcrumb || 'error';
|
|
@@ -1113,17 +1180,22 @@ function interceptFetch() {
|
|
|
1113
1180
|
url,
|
|
1114
1181
|
status: 0,
|
|
1115
1182
|
duration,
|
|
1116
|
-
error:
|
|
1183
|
+
error: err.message,
|
|
1184
|
+
errorType,
|
|
1117
1185
|
},
|
|
1118
1186
|
});
|
|
1119
1187
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1188
|
+
// 网络错误使用独立的配置项判断是否上报
|
|
1189
|
+
if (shouldReportNetworkTypeError(errorType)) {
|
|
1190
|
+
reportHttpError({
|
|
1191
|
+
method,
|
|
1192
|
+
url,
|
|
1193
|
+
status: 0,
|
|
1194
|
+
duration,
|
|
1195
|
+
requestBody,
|
|
1196
|
+
errorType,
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1127
1199
|
throw error;
|
|
1128
1200
|
}
|
|
1129
1201
|
};
|
|
@@ -1132,9 +1204,23 @@ function interceptFetch() {
|
|
|
1132
1204
|
* 上报 HTTP 错误
|
|
1133
1205
|
*/
|
|
1134
1206
|
function reportHttpError(httpInfo, isBusinessError = false) {
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1207
|
+
let message;
|
|
1208
|
+
if (isBusinessError) {
|
|
1209
|
+
message = `Business Error ${httpInfo.method} ${httpInfo.url}`;
|
|
1210
|
+
}
|
|
1211
|
+
else if (httpInfo.status === 0 && httpInfo.errorType) {
|
|
1212
|
+
// 对于 status 0,显示具体的错误类型
|
|
1213
|
+
const errorTypeLabels = {
|
|
1214
|
+
'timeout': 'Timeout',
|
|
1215
|
+
'abort': 'Aborted',
|
|
1216
|
+
'network': 'Network Error',
|
|
1217
|
+
};
|
|
1218
|
+
const label = errorTypeLabels[httpInfo.errorType] || 'Network Error';
|
|
1219
|
+
message = `HTTP ${label} ${httpInfo.method} ${httpInfo.url}`;
|
|
1220
|
+
}
|
|
1221
|
+
else {
|
|
1222
|
+
message = `HTTP ${httpInfo.status} ${httpInfo.method} ${httpInfo.url}`;
|
|
1223
|
+
}
|
|
1138
1224
|
const errorData = {
|
|
1139
1225
|
type: isBusinessError ? 'business_error' : 'http_error',
|
|
1140
1226
|
message,
|
|
@@ -1934,8 +2020,6 @@ function createUseMonitorError(React) {
|
|
|
1934
2020
|
* 前端监控 SDK
|
|
1935
2021
|
* @description 错误监控、性能监控、行为监控
|
|
1936
2022
|
*/
|
|
1937
|
-
// SDK 版本
|
|
1938
|
-
const SDK_VERSION = '1.0.0';
|
|
1939
2023
|
/**
|
|
1940
2024
|
* 监控 SDK 主类
|
|
1941
2025
|
*/
|
|
@@ -2013,7 +2097,7 @@ class MonitorSDK {
|
|
|
2013
2097
|
// 初始化配置管理器
|
|
2014
2098
|
config.init({
|
|
2015
2099
|
...finalConfig,
|
|
2016
|
-
version: finalConfig.version ||
|
|
2100
|
+
version: finalConfig.version || version,
|
|
2017
2101
|
}, true);
|
|
2018
2102
|
this.ready = true;
|
|
2019
2103
|
this.loading = false;
|
|
@@ -2190,7 +2274,7 @@ class MonitorSDK {
|
|
|
2190
2274
|
* 获取 SDK 版本
|
|
2191
2275
|
*/
|
|
2192
2276
|
getVersion() {
|
|
2193
|
-
return
|
|
2277
|
+
return version;
|
|
2194
2278
|
}
|
|
2195
2279
|
}
|
|
2196
2280
|
// 导出单例
|