UniApp全局异常捕获与日志管理实战指南
(聚焦JavaScript层实现,Android原生部分仅作必要补充)
一、全局异常捕获核心方案
1. 使用官方推荐插件uni-app-error-handler
安装与配置(基于网页1方案优化):
npm install uni-app-error-handler # 安装插件
// main.js全局配置
import ErrorHandler from 'uni-app-error-handler';
ErrorHandler.config({
console: process.env.NODE_ENV === 'development', // 开发环境打印日志
reportUrl: 'https://api.yourdomain.com/crash', // 上报地址
reportMethod: (data) => {
// 自定义上报逻辑(如添加token)
return uni.request({
url: data.url,
method: 'POST',
header: {
'Content-Type': 'application/json',
'Authorization': uni.getStorageSync('token')
},
data: JSON.stringify(data)
});
}
});
ErrorHandler.start(); // 启动全局监听
特性:
- 自动捕获
uni
API调用错误(如uni.request
超时) - 拦截未处理的Promise拒绝(如
async/await
未用try-catch
包裹) - 支持页面级错误隔离(通过Mixin注入)
2. Vue全局错误处理器
在main.js
中补充Vue层错误拦截:
Vue.config.errorHandler = (err, vm, info) => {
console.error('[Vue全局异常]', err, info);
// 上报关键信息(过滤敏感数据)
ErrorHandler.report({
type: 'vue_error',
message: err.message,
component: vm.$options.name || 'Anonymous',
stack: err.stack
});
// 阻止默认控制台报错(可选)
return false;
};
适用场景:
- 组件渲染错误(如模板语法错误)
- 观察者
watch
逻辑异常
3. 网络请求统一拦截
封装uni.request
实现全局HTTP错误处理:
// utils/http.js
const http = (options) => {
return new Promise((resolve, reject) => {
uni.request({
...options,
success: (res) => {
if (res.statusCode >= 400) {
ErrorHandler.report({
type: 'http_error',
url: options.url,
code: res.statusCode,
data: res.data
});
reject(new Error(`HTTP ${res.statusCode}`));
} else {
resolve(res.data);
}
},
fail: (err) => {
ErrorHandler.report({
type: 'network_error',
url: options.url,
message: err.errMsg
});
reject(err);
}
});
});
};
调用示例:
import http from '@/utils/http';
http({ url: '/api/user' })
.then(data => console.log(data))
.catch(err => uni.showToast({ title: '请求失败' }));
二、关键场景深度处理
1. 异步操作异常捕获
Promise链式调用:
// 使用.catch统一处理
getUserInfo()
.then(updateProfile)
.catch(err => {
ErrorHandler.report({ type: 'user_flow', error: err });
uni.showModal({ content: '操作失败,请重试' });
});
async/await最佳实践:
async function initData() {
try {
const data = await fetchData();
this.list = data;
} catch (e) {
ErrorHandler.report(e);
uni.showToast({ icon: 'none', title: '加载失败' });
}
}
2. 组件生命周期错误隔离
// 页面级错误处理(独立于全局)
export default {
onError(err) {
console.error('页面级异常:', err);
// 特殊场景上报(如支付页面)
if (this.$route.path === '/pages/pay') {
ErrorHandler.report({ type: 'pay_error', detail: err });
}
}
}
三、Android原生异常补充处理(精简版)
适用场景:WebView崩溃、JNI层Native错误
1. WebView崩溃监听(Java层)
// 原生代码扩展(需自行封装原生插件)
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// 触发UniApp事件
String js = String.format("uni.emit('webviewError', { code: %d, url: '%s' })", errorCode, failingUrl);
webView.evaluateJavascript(js, null);
}
});
UniApp层监听:
// 接收原生事件
uni.on('webviewError', (data) => {
ErrorHandler.report({
type: 'webview_crash',
code: data.code,
url: data.url
});
});
2. 封装原生插件步骤(供高级需求参考):
- 使用Android Studio创建UniApp原生插件模块
- 实现
UniModule
类重写错误回调方法 - 通过
UniJSCallback
将错误信息传递至JS层 - 打包aar后导入UniApp工程
四、日志管理与调试技巧
1. 关键日志字段设计(基于网页3优化)
字段 | 示例值 | 说明 |
---|---|---|
platform | android | 平台类型 |
error_type | js_runtime | 错误分类 |
route | /pages/index | 当前页面路径 |
sdk_version | 3.6.18 | UniApp SDK版本 |
network | wifi | 网络状态 |
2. 开发环境调试技巧
- 实时日志:使用
HBuilderX
内置的console.debug
输出彩色日志 - Vue Devtools:通过
android:debuggable="true"
启用Chrome远程调试 - 性能监控:
uni.getPerformance()
获取启动耗时、内存占用
3. 生产环境日志策略
// 按等级过滤上报
ErrorHandler.config({
reportLevels: ['error', 'warn'], // 仅上报错误和警告
beforeReport: (log) => {
// 脱敏处理(如手机号)
log.message = log.message.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
return log;
}
});
五、性能优化与稳定性保障
-
错误降级策略:
- 网络异常时启用本地缓存数据
- 连续崩溃3次后跳转至“系统维护”页
-
内存泄漏预防:
// 定时清理全局事件监听 let listeners = []; const addListener = (event, callback) => { const handler = uni.on(event, callback); listeners.push(handler); }; // 页面销毁时释放 onUnload(() => { listeners.forEach(handler => handler.off()); });
-
异常恢复机制:
// 关键流程添加重试逻辑 let retryCount = 0; const fetchData = async () => { try { return await http({ url: '/api/data' }); } catch (e) { if (retryCount < 3) { retryCount++; return fetchData(); } else { throw new Error('Maximum retries exceeded'); } } };
六、总结
全局异常捕获需建立分层防御体系:
- 基础层:
uni-app-error-handler
+ Vue全局拦截 - 业务层:关键页面独立错误处理 + HTTP统一封装
- 监控层:日志脱敏 + 分级上报 + 预警阈值设置
建议将错误统计接入可视化平台(如自建ELK系统),重点关注:
- 高频错误类型TOP5
- 崩溃率与页面退出率关联分析
- 设备/版本维度异常分布
代码实现参考来源:,日志字段设计优化自