这里所说的前端错误是指,在用户的浏览器中出现的js报错。如下图。
此类错误有几个特征:
- 报错信息一般发生在浏览器控制台,普通用户看不到。(旧版本ie可能会弹出报错的提示框,在浏览器左下角状态栏有个错误提示的标志)
- 报错一般发生在特定版本的浏览器,偶现,或者测试时未发现。
- 报错一般影响用户某些特定操作,比如说某个按钮点不了,某个列表打不开等。
一般怎么处理错误:
在处理程序错误时,我们有几个常见的办法。一般我们默认,在开发及测试阶段,错误已经处理完了大部分。剩下的小部分的问题,重点在于如何发现此类问题,只有在发现问题之后,才能够去复现,修改,验证。
『发现』此类问题,最常见的方法是使用window.onerror函数,在页面顶部定义window.onerror,在之后的代码逻辑中,未被处理的错误会触发onerror回调。可以获取到具体的出错信息,包含:『错误消息、出错的文件、行号、列号、具体错误对象(stack)』。具体参考:https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
这么做有什么问题,以及怎么解决
跨域资源报错
如果错误是在跨域的脚本里面报出来的话,错误信息只有『Script error』,没有更详细的内容。很明显,这个也是浏览器同源策略所做的约束。具体解决办法,给script标签添加crossorigin="anonymous"属性,对应的script资源添加Access-Control-Allow-Origin:* 响应头。参考:https://blog.sentry.io/2016/05/17/what-is-script-error.html
这么做完之后,还有另外一个问题。在使用webpack打包代码的时候,我们一般会使用code split,大部分的页面逻辑都会使用chunk加载。而这些分割完的代码chunk,默认不会添加crossorigin属性。webpack也对此添加了支持,可以添加crossOriginLoading配置。参考:https://webpack.js.org/configuration/output/#output-crossoriginloading
onerror覆盖
在使用onerror的时候,大多使用window.onerror = function(){}这样的写法。这就导致一个页面里只有一个错误处理的函数,在多人协作开发的时候,嗯,确实有人会覆盖onerror。需要注意避免。
错误信息收集不全
错误信息收集不全,也是在特定的场景下出现的问题。比如说上文中的报错的示例,错误本身是在glsExam-xxx.js里面报出来的,但是因为react捕获了这个错误,然后抛出了一个异常,然后错误就变成了是react报出来的了。而公司的报错脚本只取onerror里的报错消息和报错文件,没有stack信息。这就导致看到的错误都是react在报。
这样的报错对我们来讲没有价值。解决的思路也比较简单,对gentian默认的onerror处理函数做一次封装,更新掉默认的react的报错。