我们在debug模式App发生错误会出现红屏,很容易就可以找到错误原因
在生产环境用户手中发生错误会直接闪退,并且我们也不知道发生了什么很不利于错误排查。这时我们需要错误上报,用于错误排查
官方提供了ErrorUtils用来解析错误处理
路径如下
node_modules/react-native/Libraries/Core/__mocks__/ErrorUtils.js
ReactNative版本0.62.2
const ErrorUtils = {
apply: jest.fn(execute),
applyWithGuard: jest.fn(execute),
guard: jest.fn(callback => callback),
inGuard: jest.fn().mockReturnValue(true),
reportError: jest.fn(reportError),
setGlobalHandler: jest.fn(),
};
其中setGlobalHandler我们可以拿来进行捕获错误并且做一些我们需要的事情例如上报服务器
const handleError = (e, isFatal) => {
try {
ExceptionsManager.handleException(e, isFatal);
} catch (ee) {
console.log('Failed to print error: ', ee.message);
throw e;
}
};
const ErrorUtils = require('../vendor/core/ErrorUtils');
ErrorUtils.setGlobalHandler(handleError);
1、重写ErrorUtils.setGlobalHandler
global.ErrorUtils.setGlobalHandler((error, isFatal) => {
//isFatal是否造成崩溃 __DEV__是否是调试模式
if (!isFatal || __DEV__) {
return;
}
const {message, stack} = error;
console.log(message, stack);
});
错误信息通过stack来获取,而错误位置,我们可以结合sourceMap和错误位置来定位源码。sourceMap的方法就不赘述了网上一大堆。
2、拿到错误信息我们可以选择上传到服务器用来通知我们错误信息,我这边选择通过钉钉的webHook来上报到钉钉群,你也可以任意操作
钉钉文档
errorUtils.js
import Constants from 'expo-constants';
import {Platform} from 'react-native';
import config from '../../config';
import ExceptionsManager from 'react-native/Libraries/Core/ExceptionsManager';
const {dingtalkAccessToken} = config;
//获取用户设备信息
//我这边使用Constants,这里就看你自由发挥了
const getDeviceInfo = () => {
try {
return `AppVersion: ${Constants.nativeAppVersion}\nBuildVersion: ${
Constants.nativeBuildVersion
}\nDevice isDevice: ${Constants.isDevice}\nDevice osName: ${
Platform.OS
}\nDevice deviceName: ${Constants.deviceName}`;
} catch (error) {
return '';
}
};
global.ErrorUtils.setGlobalHandler(async (error, isFatal) => {
if (!isFatal || __DEV__) {
return;
}
//你的钉钉的token
if (dingtalkAccessToken) {
try {
const deviceInfo = getDeviceInfo();
const {message, stack} = error;
const Error =
error && typeof error === 'string'
? `Error:${error}`
: `${message ? `Error: ${message}\n` : ''}${
stack ? `Stack: ${stack}` : ''
}`;
const body = JSON.stringify({
msgtype: 'text',
text: {
content: `你的应用发生崩溃 ${Error}\n\n${deviceInfo}`,
},
});
await fetch(
`https://oapi.dingtalk.com/robot/send?access_token=${dingtalkAccessToken}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
body,
},
);
} catch (e) {
console.log(e, '=setGlobalHandler');
}
}
ExceptionsManager.handleException(error, isFatal);
});
在app入口文件我们只需
import './app/utils/common/errorUtils'; //添加这一行
import App from './app/App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
网友评论