美文网首页
优雅处理前端异常

优雅处理前端异常

作者: Wang_Yong | 来源:发表于2020-07-23 10:59 被阅读0次

    一、为什么要处理异常?

    1 增强用户体验
    2 远程定位问题
    3 未雨绸缪 发现问题
    4 无法浮现问题 尤其是移动端 机型 系统都是问题
    5 完善的前端方案 前端监控系统

    二、需要处理哪些异常

    1、js预发错误 代码异常
    2、ajax请求异常
    3、静态资源家在异常
    4、promise异常
    5、iframe异常
    6、跨域script error
    7、崩溃和卡顿

    Try-Catch的误区

    try-catch只能捕获同步的运行时错误。对语法和异步的错误无能为力,捕获不到。
    1、同步运行时错误


    同步运行时错误.png

    2、不能捕获具体的语法错误,只有一个语法错误提示


    这个错误基本上没有啥用.png
    3、异步错误
    image.png
    异步异常 捕获不到

    四、window.onerror不是万能的

    当js运行时错误发生时,window会触发一个ErrorEvent接口的error事件,并执行window.onerror

    /**
    message: 错误信息
    source: 出错文件
    lineno: 行号
    error: 错误对象
    */
    window.onerror = function(message, source, lineno, colno, error){
       console.log('异常捕获', {message, source, lineno, colno, error})
    }
    

    1、同步信息错误


    window.error同步信息出错.png

    2、语法错误


    语法信息错误.png
    3、模拟异步运行时的错误
    setTimeout(() => {
      michael
    }, 3000)
    
    异步错误.png

    补充一点:window.onerror 函数只有返回true的时候,异常才不会向上抛出,否则控制台还是会显示Uncaught Error: XXXXXXXX

    注意:
    onerror最好写在所有的js脚本的前面,否则有可能捕获不到错误。
    onerror无法捕获语法错误

    五、winodw.addEventListener 静态资源加载异常

    当资源加载失败,加载资源的元素会触发一个Event接口的error事件,并执行该元素上的onerror处理函数

    window.addEventListener('error', function(error){
      console.log('捕获到异常',error)
    }, true)
    
    image.png

    六、Promise Catch

    primise中使用catch可以获取到异步的error, 但是如果忘了怎么办
    解决方案:为了防止有漏掉的Promise异常,建议在全局增加一个对unhandlerejection的监听,用来全局监听 Uncaught Promise Error

    window.addEventListener('unhandledrejection', function(e) {
      e.preventDefault()
      console.log(e)
      return true
    })
    Promise.reject('error')
    
    错误信息.png

    七、vue errorHandler

    Vue.config.errorHandler = (err, vm, info) => {
       console.error('通过vue errorHandler捕获的错误');
       console.error(err);
       console.error(vm);
       console.error(info);
    }
    

    八、react中异常捕获

    componentDidCatch(error, info){
       
    }
    

    注意点:error boundaries并不会捕获下面错误
    1、事件处理器
    2、异步代码
    3、服务端的渲染代码
    4、在error boundaries区域内的错误

    九、iframe异常

    <iframe src="./frame.html"></iframe>
    window.frames[0].onerror = function(message, source, lineno, colno, error){
      console.log('异常', { message, source, lineno, colno, error })
      return true
    }
    

    十、Script error

    基本上跨域问题

    十一、崩溃和卡顿

    利用window对象的load和beforeunload事件实现了网页崩溃的监控。

    window.addEventListener('load', function(){
      sessionStorage.setItem('good_exit', 'pending')
      setInterval(function(){
        sessionStorage.setItem('time_before', new Date().toString())
      }, 1000)
    })
    
    window.addEventListener('beforeunload', function(){
      sessionStorage.setItem('good_exit', 'true')
    })
    
    if(sessionStorage.getItem('good_exit') && sessionStorage.getItem('good_exit') !== 'true'){
        alert('Hey, welcome back from your crash, looks like you crashed on: ' + sessionStorage.getItem('time_before_crash'))
    }
    

    2、基于以下原因,我们可以使用 Service Worker 来实现网页崩溃的监控:
    Service Worker 有自己独立的工作线程,与网页区分开,网页崩溃了,Service Worker 一般情况下不会崩溃;Service Worker 生命周期一般要比网页还要长,可以用来监控网页的状态;网页可以通过 navigator.serviceWorker.controller.postMessage API 向掌管自己的 SW 发送消息。

    知乎上关于service work来监控的方案

    十二 错误上报

    1、通过ajax 风险:ajax本身也有报错风险,跨域问题
    2、动态创建img标签的形式

    function report(error){
      let url = 'http://www.baicuu.com'
      new Image().src = `${url}?logs=${error}`
    }
    

    收集信息太多怎么办?如何减少服务器的压力

    Report.send = function(data){
       if(Math.random < 0.3) {
        send(data)
      }
    }
    

    视情况定,用户特征等等

    十三 总结

    如何优雅的处理异常
    1、可疑区增加try-catch
    2、全局监控js异常
    3、全局监控静态资源异常 window.addEventListener
    4、
    5、
    6、监控网页崩溃:window对象的load 和 beforeunload
    7、跨域crossOrigin
    分类型解决异常

    https://mp.weixin.qq.com/s/prf-mXexBh1Ie-ctq9FnzA

    相关文章

      网友评论

          本文标题:优雅处理前端异常

          本文链接:https://www.haomeiwen.com/subject/ziwzkktx.html