UniApp全局异常捕获与日志管理实战指南

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();  // 启动全局监听  

特性

  • 自动捕获uniAPI调用错误(如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. 封装原生插件步骤(供高级需求参考):
  1. 使用Android Studio创建UniApp原生插件模块
  2. 实现UniModule类重写错误回调方法
  3. 通过UniJSCallback将错误信息传递至JS层
  4. 打包aar后导入UniApp工程

四、日志管理与调试技巧
1. 关键日志字段设计(基于网页3优化)
字段示例值说明
platformandroid平台类型
error_typejs_runtime错误分类
route/pages/index当前页面路径
sdk_version3.6.18UniApp SDK版本
networkwifi网络状态
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;  
    }  
});  

五、性能优化与稳定性保障
  1. 错误降级策略

    • 网络异常时启用本地缓存数据
    • 连续崩溃3次后跳转至“系统维护”页
  2. 内存泄漏预防

    // 定时清理全局事件监听  
    let listeners = [];  
    
    const addListener = (event, callback) => {  
        const handler = uni.on(event, callback);  
        listeners.push(handler);  
    };  
    
    // 页面销毁时释放  
    onUnload(() => {  
        listeners.forEach(handler => handler.off());  
    });  
    
  3. 异常恢复机制

    // 关键流程添加重试逻辑  
    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');  
            }  
        }  
    };  
    

六、总结

全局异常捕获需建立分层防御体系

  1. 基础层uni-app-error-handler + Vue全局拦截
  2. 业务层:关键页面独立错误处理 + HTTP统一封装
  3. 监控层:日志脱敏 + 分级上报 + 预警阈值设置

建议将错误统计接入可视化平台(如自建ELK系统),重点关注:

  • 高频错误类型TOP5
  • 崩溃率与页面退出率关联分析
  • 设备/版本维度异常分布

代码实现参考来源:,日志字段设计优化自

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值