此文已由作者张磊授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

前言:

后端服务一般都有监控措施,一般可以及时发现线上错误,但是很多项目的前端却没有线上报警服务,即使有错误,前端根本无法感知,但实际上用户使用的系统、浏览器等环境十分复杂,还是有比较高的概率出现 bug 的。这时候线上错误的发现,一般有三个方向,要么依赖于用户报告,要么依赖于测试发现,要么是自己使用中发现问题。依靠用户报告,这就严重影响了体验,而且很多用户不会报告或者其他原因复现率低,导致没有报告。所以为了解决该问题,那前端需要一个服务,遇到错误的时候,能主动上报问题,并作提醒,进行排查。同时也可以在测试环境也部署该服务,有时候测试没有发现的问题,但这个主动上报就能帮我们提早发现代码 bug,再者我们可以和用户同时接收到错误信息,那么我们就可以及早修复问题,把问题的影响尽可能的缩小,静默解决。

环境:

项目是 NEJ 和 regular 开发的,以 SPA 页面为主。

实施:

这里是使用 apm 作为线上报警的基础服务。同时对线上线下环境分开处理。

阶段成果:

上线该服务几个月,线上线下的报错发现的有几十个。最近越来越稳定,出错率越来越低了。当然也遇到了一些很难复现的 bug。

错误分析:

如果把错误仅仅当成错误来看,这肯定是不对的,应该从错误中发现些什么,以后注意那些坑,毕竟已经有几十个错误作为参照物了,也可以拿来分析了。错误可以归为几类:

  1. Uncaught TypeError: Cannot read property 'ref0' of null这种一般是在 setTimeout 里对 this.$refs 进行操作,一般做法是在 setTimeout 里,进行二次检测,但更好的做法是 clearTimeout。

  2. Uncaught TypeError: Cannot read property '__cache' of undefined这种一般是在 setTimeout 里对接口请求进行操作,此时路由页面已经触发 destory 掉了,导致访问 this 对象获取不到对应的方法。一般做法是在 setTimeout 里,进行二次检测,但更好的做法是 clearTimeout。

  3. 几率出错线下测试代码无问题发生,但是线上用户报错,这里一般是没有写清楚边界情况造成的。解决方案,通过错误查找到对应代码,分析逻辑。

  4. Uncaught TypeError: Cannot read property 'indexOf'/'replace' of undefined后端数据返回不规范造成的,可能约定是 string 但是实际中没有返回值,又或者接口的错误处理有问题造成的。实际上两者皆有。

  5. 引入公司其他服务脚本报错
    这些脚本的错误,一般是通知相关人员进行 fix。

  6. 因为扩展导致的报错
    曾经一个测试装了一个扩展,只要访问某些页面,短时间可以出现 1000+ 的错误

  7. 第三方浏览器,或者手机浏览器报错

    错误信息    
    SecurityError (DOM Exception 18): Blocked a frame with origin "https://a.com" from accessing a frame with origin "https://b.com". Protocols, domains, and ports must match.
    堆栈信息    
    qqIframeRef@https://a.com/#/m/a/:54:67qqGetVideos@https://a.com/#/m/a/:68:53initVideoInstance@https://a.com/#/m/a/:115:45hook@https://a.com/#/m/a/:151:42global code@https://a.com/#/m/a/:320:26

    这种一般是第三方加的脚本,忽略即可。

  8. Uncaught ReferenceError: t is not defined这个错误,一开始觉得和1、2是类似的,边界未处理,再加上是 lib 库的代码。后来实际上研究了逻辑,才发现使用的 lib 部分代码丢失,在处理 ctrl + up 的时候的回调函数没了。。。后续解决方案,研究了下逻辑,不影响使用,删掉该段代码。

静态资源和后台服务不同源

后来对静态资源单独一个域名,一开始没有考虑到不同源的问题,apm 不报错,以为是代码质量好了很多。后来发现错误集中在 firefox、ie 上,错误信息都是 script error。想到域名的问题,才发现 apm 相当于停止工作一段时间了。这个问题的解决方案,需要对 nej 打包进行处理,允许 script 标签添加属性。同时允许异步加载的 script 添加属性即可。接着对静态资源的服务器添加跨域 header 配置。

Access-Control-Allow-Origin: *

参考

  1. https://stackoverflow.com/questions/28901166/how-do-i-add-the-crossorigin-tag-to-a-dynamically-loaded-script

  2. https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalEventHandlers/onerror

  3. http://www.alloyteam.com/2017/03/jserror1/

免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击

相关文章:
【推荐】 视觉设计师的进化
【推荐】 git使用那些事儿
【推荐】 认识用户访谈

项目接入apm后错误报警总结的更多相关文章

  1. Spring Boot接入 apollo 后启动 dubbo 报错

    原文地址:https://xobo.org/spring-boot-apollo-dubbo-xml-error/ 某Spring Boot项目接入 apollo 后启动 dubbo 报错Caused ...

  2. java 项目 存入mysql后 变问号 MySql 5.6 (X64) 解压版 1067错误与编码问题的解决方案

    [参考]MySQL 5.7.19 忘记密码 重置密码 my.ini示例 服务启动后停止 环境 Java环境JDK1.8  安装好了 mysql-5.6.38-winx64  idea2016(64) ...

  3. 《转》iOS 平台 Cocos2d-x 项目接入新浪微博 SDK 的坑

    最近在做一个 iOS 的 cocos2d-x 项目接入新浪微博 SDK 的时候被“坑”了,最后终于顺利的解决了.发现网上也有不少人遇到一样的问题,但是能找到的数量有限的解决办法写得都不详细,很难让人理 ...

  4. 原有vue项目接入typescript

    原有vue项目接入typescript 为什么要接入typescript javascript由于自身的弱类型,使用起来非常灵活. 这也就为大型项目.多人协作开发埋下了很多隐患.如果是自己的私有业务倒 ...

  5. PC、h5项目接入第三方支付宝扫码登录、扫码付款

    首先介绍一下pc项目接入支付宝扫码支付. 1.pc.移动接入支付宝扫码支付. 其实这个逻辑很简单,前端所需要处理的不是很多,后台会给一个连接,前端只需要将要支付的订单id拼接在这个连接上,然后打开跳转 ...

  6. 执行makemigrations后错误集锦

    在项目配置xadmin后,执行python manage.py makemigrations后出现了很多问题: 1.ModuleNotFoundError: No module named 'futu ...

  7. vue中npm run dev运行项目不能自动打开浏览器! 以及 webstorm跑vue项目jshint一直提示错误问题的解决方法!

    vue中npm run dev运行项目不能自动打开浏览器!以及 webstorm跑vue项目jshint一直提示错误问题的解决方法! 1.上个项目结束就很久没有使用vue了,最近打算用vue搭建自己的 ...

  8. Java项目接入sso单点登录

    最近在落地cat(java开发的一款开源监控系统)接入公司的内部项目,其中有项需求是接入公司的sso单点登录系统.研究了公司之前java项目接入sso系统,大部分是采用spring框架,然后依赖spr ...

  9. vue项目更换目录后执行npm run dev 就报错(新手进)

    在我们搭建好一个VUE项目的环境后,觉得这个项目存放的位置不好,想移动一下,但是移动后我们发现执行npm run dev就会报下面的错误: 明明只是移动了一下位置,就报错,实在是太恶心了. 但是只要我 ...

随机推荐

  1. ruanjiangongcheng1

    软体工程的方法有很多方面的意义.包括专案管理,分析,设计,程序的编写,测试和质量控制. 软体设计方法可以区别为重量级的方法和轻量级的方法.重量级的方法中产生大量的正式文档. 著名的重量级开发方法包括I ...

  2. Java -- eclipse常用快捷键

  3. Tkenter之API测试系统界面设计

    # -*- coding: UTF-8 -*- from Tkinter import * tk=Tk() tk.geometry('500x400+500+200') tk.title('API测试 ...

  4. hdu 4514 湫湫系列故事――设计风景线(求树的直径)

    随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好.  现在已经勘探确定了n个位置 ...

  5. Selenium-免登录的实现

    场景: 经常会遇到登录需要验证码这样类似的情况 解决方案: 1.万能验证码 2.利用cookies来实现,问开发哪个cookies值是登录后需要的,把这个值带上即可 3.利用火狐浏览器的profile ...

  6. 唐诗掠影:基于词移距离(Word Mover's Distance)的唐诗诗句匹配实践

    词移距离(Word Mover's Distance)是在词向量的基础上发展而来的用来衡量文档相似性的度量.   词移距离的具体介绍参考http://blog.csdn.net/qrlhl/artic ...

  7. C语言小程序(三)、判断两个日期之差

    输入两个日期,计算之间相差多少天. 用了两种方法实现,第二种利用结构体,代码比较清晰,其余的都一样. 1.普通的写法 #include <stdio.h> int leapyear(int ...

  8. Sublime Text2中Evernote 插件的使用

    Sublime Text2是个强大的编辑器, 有好多插件供我们使用, 其中有个插件SublimeEvernote, 可以把代码发送到Evernote里. 但是没找见使用说明, 今天看了下Sublime ...

  9. 【转】 Pro Android学习笔记(五五):调试和分析(3):adb命令、模拟器控制台和StrictMode

    目录(?)[-] adb命令 模拟器Console StrictMode adb命令 我们在学习SQLite的使用,介绍过部分adb命令的使用,见Pro Android学习笔记(五):了解Conten ...

  10. Guice 学习

    Guice: 是一个轻量级的DI框架. 不需要繁琐的配置,只需要定义一个Module来表述接口和实现类,以及父类和子类之间的关联关系的绑定,如下是一个例子. http://blog.csdn.net/ ...