tengits-debug-tool
Version:
debug-tool for react-native
165 lines (144 loc) • 6.63 kB
JavaScript
import React from 'react';
import { Alert } from 'react-native';
import {costTimeWork, dateFormat, isEmpty, getApiName} from './utils/DebugUtils';
import FloatPanelController from './views/FloatPanelController';
let httpRequestLogs = [], webViewLoadLogs = [], normalLogs = [], exceptionLogs = [];
export default class DebugManager {
static debugLogOff = true;
static setDebugLog(isOn) {
DebugManager.debugLogOff = !isOn;
}
static initServerUrlMap(serverUrlMap, currentUrl, changeCallback) {
DebugManager.currentUrl = currentUrl;
DebugManager.serverUrlMap = serverUrlMap;
DebugManager.changeCallback = changeCallback;
return DebugManager;
}
static initDeviceInfo(deviceInfo) {
DebugManager.DeviceInfo = deviceInfo;
return DebugManager;
}
static initConfigs(config) {
DebugManager.Configs = config;
return DebugManager;
}
static initJSException(allowedInDevMode = false, customHandler = this.appendExceptionLogs) {
if (typeof allowedInDevMode !== "boolean" || typeof customHandler !== "function"){
console.log("setJSExceptionHandler is called with wrong argument types.. first argument should be callback function and second argument is optional should be a boolean");
console.log("Not setting the JS handler .. please fix setJSExceptionHandler call");
return DebugManager;
}
const allowed = allowedInDevMode ? true : !__DEV__;
if (allowed) {
global.ErrorUtils.setGlobalHandler((error, isFatal)=>{
console.log(error);
customHandler && customHandler(error, isFatal);
if(isFatal) {
Alert.alert("出现异常,请截图上报",
`错误: ${(isFatal) ? 'Fatal:' : ''} ${error?.name} ${error?.message} ${error?.stack}`, [
{
text: '关闭',
onPress: () => {
}
}
])
}
});
console.error = (message, error) => global.ErrorUtils.reportError(error); // sending console.error so that it can be caught
} else {
console.log("Skipping setJSExceptionHandler: Reason: In DEV mode and allowedInDevMode = false");
}
require('promise/setimmediate/rejection-tracking').enable({
allRejections: true,
onUnhandled: (id, error) => {
const warning =
`Possible Unhandled Promise Rejection (id: ${id}):\n` +`${error?.message}\n` + error?.stack;
console.warn(warning);
customHandler && customHandler(error, id);
},
onHandled: (id) => {
const warning =
`Promise Rejection Handled (id: ${id})\n` +
'This means you can ignore any previous messages of the form ' +
`"Possible Unhandled Promise Rejection (id: ${id}):"`;
console.warn(warning);
},
});
return DebugManager;
}
static appendExceptionLogs(error, isFatal) {
costTimeWork(() => {
exceptionLogs.unshift({log: `${isFatal}|${error?.name} ${error?.message} ${error?.stack}`, timeStr: dateFormat(new Date(), 'MM月dd日 hh时mm分ss秒S毫秒')});
if (exceptionLogs.length > 20) normalLogs.splice(10)//若url个数大于100,则删除前20个
})
}
static appendHttpLogs(params, response, parseResult) {//Http请求日志(请求结果过大的数据不保存) parseResult->用于临时解析
if (DebugManager.debugLogOff || isEmpty(response)) return;
if (isEmpty(response._bodyText) && isEmpty(parseResult)) {
let reader = new FileReader();
reader.addEventListener('loadend', () => this.appendHttpLogs(params, response, reader.result));
reader.readAsText(response._bodyBlob);
} else {
let resultStr = isEmpty(parseResult) ? response._bodyText : parseResult;
costTimeWork(() => {
let obj = {
url: response.url,
method: params.method,
apiName: getApiName(response.url),
headers: JSON.stringify(params.headers),
body: JSON.stringify(params.body),
result: resultStr.substr(0, 2000),
completed: resultStr.length < 2000,
timeStr: dateFormat(new Date(), 'MM月dd日 hh时mm分ss秒S毫秒'),
};
httpRequestLogs.unshift(obj);
if (httpRequestLogs.length > 30) {
httpRequestLogs.splice(10);
}//若日志个数大于30,则删除前10个
});
}
}
static appendWebViewLogs(loadUrl) {//webView加载Url
if (DebugManager.debugLogOff) return;
costTimeWork(() => {
webViewLoadLogs.unshift({url: loadUrl, timeStr: dateFormat(new Date(), 'MM月dd日 hh时mm分ss秒S毫秒')});
if (webViewLoadLogs.length > 100) {
webViewLoadLogs.splice(20);
}//若url个数大于100,则删除前20个
});
}
static appendLogs(text) {
if (DebugManager.debugLogOff) return;
costTimeWork(() => {
normalLogs.unshift({log: text, timeStr: dateFormat(new Date(), 'MM月dd日 hh时mm分ss秒S毫秒')});
if (normalLogs.length > 100) normalLogs.splice(20)//若url个数大于100,则删除前20个
})
}
static getHttpLogs() {//获取Http请求日志列表
return httpRequestLogs;
}
static clearHttpLogs() {//清除Http请求日志列表
httpRequestLogs = [];
}
static getWebLoadLogs() {//获取webView加载日志列表
return webViewLoadLogs;
}
static getLogText() {//获取其它日志列表
return normalLogs;
}
static getExceptionLogText() {
return exceptionLogs;
}
static destroy() {
httpRequestLogs = [];
webViewLoadLogs = [];
normalLogs = [];
}
static showFloat(RootSiblings) { // type of RootSiblings (3.x)
if (this.sibling) {
this.sibling.update(<FloatPanelController close={() => this.sibling.destroy()}/>)
} else {
this.sibling = new RootSiblings(<FloatPanelController close={() => this.sibling.destroy()}/>);
}
}
}