文档章节

前端一站式异常监控捕获方案

ouven
 ouven
发布于 2017/05/03 15:10
字数 1212
阅读 1855
收藏 118
点赞 2
评论 0

一、前端异常监控的重要性

  软件异常监控常常直接关联到软件本身的质量,完备的异常监控体系常常能够快速定位到软件运行中发生的问题,并能帮助我们快速定位异常的源头,提升软件质量。

  在服务器开发中,我们常常使用日志来记录请求的错误和服务器异常问题,但是在客户端,前端应用直接部署运行在用户的浏览器中,如果发生错误,应该怎样去捕获并传送给服务器呢?前端错误日志传送给服务器很简单,在异常发生时直接发请求就可以了,下面我们主要讨论下错误的捕获方案。

二、现有的异常监控方案

  • window.onerror全局异常捕获

  目前前端捕获页面异常的方式主要有两种,window.onerror捕获整个页面中运行的错误,它的局限是对于跨域的JavaScript脚本需要添加跨域支持,也就是需要涉及服务器的修改成本,否则无法获取到运行时具体的堆栈错误信息,而是"script error"的信息,不利于我们定位问题。

window.onerror = function(msg, file, row, column, errorObj) {
    console.log(msg); // script error.
    console.log(file); // 
    console.log(row); // 0
    console.log(column); // 0
    console.log(errorObj); // {}
    setTimeout(function() {
        // 发送请求上报日志信息
        errorReport(e.name, e.message + e.stack);
    }, 5000);
}
<script src="//domain.com/path/main.js" crossorigin></script>
  • try-catch运行时解决方案

  现有的另一中方案则是try-catch,对于某个方法函数,我们可以这样定义来捕获函数里面运行时的异常,但是try-catch只能捕获当前单个作用域下的异常。另外,使用try-catch会带来一定的性能损耗,根据循环测试,平均大概会损失6%~10%的性能,但是为了提升应用的质量和稳定性,这些是可以接受的。

function wrapFunction(fn) {
    return function() {
        try {
            return fn.apply(this, arguments);
        } catch (e) {
            console.log(e);
            _errorProcess(e);
            return;
        }
    };
}

// 之后fn函数里面的代码运行出错时则是可以被捕获到的了
fn = wrapFunction(fn);

// 或者异步函数里面的回调函数中的错误也可以被捕获到
var _setTimeout = setTimeout;
setTimeout = function(fn, time){
    return _setTimeout(wrapFunction(fn), time);
}

// 模块定义函数也可以做重写定义
var _require = require;
require = function(id, deps, factory) {
    if (typeof(factory) !== 'function' || !factory) {
        return _require(id, deps);
    } else {
        return _require(id, deps, wrapFunction(factory));
    }
};

  那么我们可以对常用的模块入口函数进行重定义,包括define,require等,这样模块中的主要作用域中的异常都可以通过try-catch来捕获了。在之前的处理方法中,这种方法是非常有效的,直接可以拿到大多数错误栈中的异常和堆栈信息。

三、改进的一站式解决方案

  React开发时代,这种方式就不能直接使用了,我们知道React的组件都是class,其实也就是构造函数,这里普及下class和构造函数其实是非常类似的,class A除了constructor为class A,其它信息和function A类似,typeof获取的类型也相同。但是我们是没办法把构造函数A直接装入try-catch中运行的,因为需要通过关键字new进行实例化,并创建新的作用域。

  此时我们要处理的问题其实是捕获React中属性方法中的错误,应该还记得,JavaScript中函数有个特殊的属性prototype,当函数作为构造函数是,prototype中的属性就成了实例化后的属性方法,而且这一属性对class同样生效。那么我们可以对React中class的prototype这个特殊属性的内容进行处理,对Component中的方法函数进行封装。

function defineReact(Component) {

    var proto = Component.prototype;

    for (var key in proto) {
        if (typeof(proto[key]) === 'function') {
            proto[key] = _wrapFunction(proto[key]);
        }
    }

    return Component;
}

  这样通过实例化产生的React组件中的内部方法中的错误就可以被捕获到了。

class component extends React.Component {
    componentDidMount(){
        var a = {};
        console.log(a.b.c);
    }
    render() {
        return <div>hello world</div>;
    }
}
export default defineReact(component);

  这里添加defineReact的操作就可以放到构建打包工具中去处理了,这样就避免了我们对代码层直接进行修改。

React直接报错不利于定位问题

封装后直接获取堆栈错误

四、小结

  小结一下,其实和原有的方式差别不大,仍然通过try-catch的方式,覆盖到React组件prototype属性中进行异常捕获,极大增加了错误捕获范围,不仅能帮助我们快速定位开发中的问题,也能捕获React线上应用的运行时错误。

完整例子:https://github.com/ouvens/tryjs

原文链接:http://jixianqianduan.com/frontend-weboptimize/2017/05/04/front-end-react-error-capture.html

© 著作权归作者所有

共有 人打赏支持
ouven

ouven

粉丝 105
博文 30
码字总数 77829
作品 0
深圳
高级程序员
阿里云产品头条(2018年3月刊)

阿里云新产品发布 1、 弹性裸金属服务器 正式商用 (国内站、国际站) 弹性裸金属服务器是一款同时兼具虚拟机弹性和物理机性能及特性的新型计算类产品,是基于阿里云完全自主研发的下一代虚拟...

云攻略小攻 ⋅ 04/26 ⋅ 0

2017前端监控系统探索总结

背景 在当下互联网行业,监控概念与重要性已经不需要再进行阐述,然而监控分为多种,对物理层(机房,云主机)的监控,对传输链路的监控,对已部署服务的监控等等,而后端的代码通常直接运行...

⋅ 2017/12/26 ⋅ 0

阿里·云效平台成2016北京QCon大会亮点

4月21~23日,2016年北京QCon大会在北京国际会议中心举行,大会邀请了互联网领域的大咖分享国内外技术交流的最新趋势资讯,涉及自动化运维、移动开发挑战、移动测试技术、大数据平台架构等精彩...

云效平台 ⋅ 2016/04/21 ⋅ 0

Spring事务异常回滚,捕获异常不抛出就不会回滚

最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了....... 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志。但是这边情况来了,当这个方法异常时候 日志是打...

binhu ⋅ 2015/11/23 ⋅ 0

基于 Vue 的前端解决方案 - renren-fast-vue

renren-fast-vue基于vue、element-ui构建开发,实现renren-fast后台管理前端功能,提供一套更优的前端解决方案。 renren-fast-vue基于vue、element-ui构建开发,实现renren-fast后台管理前端...

字母大号被盗了 ⋅ 04/16 ⋅ 0

使用云效在阿里云上进行一站式开发运维

摘要: 云效,一站式企业协同研发云,提供从“需求->开发->测试->发布->运维->运营”端到端的协同服务和研发工具支撑。云效将计划与其他云产品合作,进一步优化一站式体验。 导读 作为一站式企...

阿里云云栖社区 ⋅ 04/12 ⋅ 0

坚守数据之道,帆软2017百城巡展启航合肥

过去的一年,帆软携带大数据BI方案和移动数据分析走过北京、上海、广州、南京、杭州等23座城市,以标杆客户案例讲解数据管理之道,希望能唤起企业对数据的重视,让数据化管理之风惠及IT。 新...

玄学酱 ⋅ 04/16 ⋅ 0

电商总结(一)小型电商网站的架构

  又是一年年底了,这一年,从传统软件行业进入到电商企业,算是一次转行了吧。刚开始,觉得电商网站没有什么技术含量,也没有什么门槛,都是一些现有的东西堆积木似的堆出来而已。然而,真...

章为忠 ⋅ 2016/02/01 ⋅ 0

漂亮得不像实力派!

晚上正在和 Cloud Insight 技术负责人争论「Null Point Mode」问题时,听说 OneAPM 官网上了 BootCSS 的优站精选。在一堆设计精巧的外文网站中,一抹映衬着中文的蓝色确实让人有些振奋。 老板...

OneAPM蓝海讯通 ⋅ 2015/09/11 ⋅ 0

Spring事务异常回滚,捕获异常不抛出就不会回滚

最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了....... 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志。但是这边情况来了,当这个方法异常时候 日志是打...

巴顿 ⋅ 2016/01/05 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Boost库编译应用

版本:Boost 1.66.0 Windows库编译 官网指南:直接执行bootstrap.bat处理文件即可,可以我却遇到一堆的问题。 环境:Windows 10 + Visual Studio 2017 Boost编译出来库命名 boost库生成文件命...

水海云 ⋅ 11分钟前 ⋅ 0

解决Eclipse发布到Tomcat丢失依赖jar包的问题

如果jar文件是以外部依赖的形式导入的。Eclipse将web项目发布到Tomcat时,是不会自动发布这些依赖的。 可以通过Eclipse在项目上右击 - Propertics - Deployment Assembly,添加“Java Build ...

ArlenXu ⋅ 11分钟前 ⋅ 0

iview tree组件层级过多时可左右滚动

使用vue+iview的tree组件,iview官网iview的tree树形控件 问题描述:tree层级过多时左右不可滚动 问题解决:修改overflow属性值 .el-tree-node>.el-tree-node_children { overflow: vi...

YXMBetter ⋅ 13分钟前 ⋅ 0

分布式锁

1.通过数据库实现 http://www.weizijun.cn/2016/03/17/%E8%81%8A%E4%B8%80%E8%81%8A%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81%E7%9A%84%E8%AE%BE%E8%AE%A1/ 2.ZK实现:curator-recipes分布式锁的......

素雷 ⋅ 21分钟前 ⋅ 0

Sublime Text3 快捷键

选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本。 Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑。举个栗子:快速选中并更改所有相同的变量名...

AndyZhouX ⋅ 28分钟前 ⋅ 0

XamarinAndroid组件教程RecylerView自定义适配器动画

XamarinAndroid组件教程RecylerView自定义适配器动画 如果RecyclerViewAnimators.Adapters命名空间中没有所需要的适配器动画,开发者可以自定义动画。此时,需要让自定义的动画继承Animation...

大学霸 ⋅ 28分钟前 ⋅ 0

eureka 基础(二)

使用Eureka服务器进行身份验证 如果其中一个eureka.client.serviceUrl.defaultZone网址中包含一个凭据(如http://user:password@localhost:8761/eureka)),HTTP基本身份验证将自动添加到您...

明理萝 ⋅ 31分钟前 ⋅ 1

Kubernetes(五) - Service

Kubernetes解决的另外一个痛点就是服务发现,服务发现机制和容器开放访问都是通过Service来实现的,把Deployment和Service关联起来只需要Label标签相同就可以关联起来形成负载均衡,基于kuberne...

喵了_个咪 ⋅ 31分钟前 ⋅ 0

更新队友POM文件后报错

打开报错的地方的pom及其引用方法所在文件的pom,观察其版本号是否一致,不一致进行更改

森火 ⋅ 45分钟前 ⋅ 0

IDEA使用sonarLint

一、IDEA如何安装SonarLint插件 1.打开 Idea 2.点击【File】 3.点击【Settings】 4.点击【Plugins】 5.在搜索栏中输入“sonarlint”关键字 6.点击【Install】进行安装 7.重启Idea 二、IDEA如...

开源中国成都区源花 ⋅ 50分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部