共计 3115 个字符,预计需要花费 8 分钟才能阅读完成。
背景
家喻户晓,简直没有一个开发者可能做到开发时 100% 没有 Bug,那么一旦咱们的产品出了问题,疾速定位问题是迫切需要做的事。好在咱们在 Web 场景中 Js 运行出现异常不会导致 JS 引擎解体,最多只会终止以后执行的工作。而后逐级上抛谬误,相似冒泡事件,在遇到最近的一层 catch 时进行上抛,如果两头都没有错误处理的 catch 时,直至 window 对象完结。那么明天就与大家一起探讨一下咱们在 Web 场景中的异样谬误数据如何收集以及如何上报。
谬误类型
想要获取到绝对残缺的异样谬误数据,先要理解在 Web 中常见的异样谬误都有哪些。
Js 执行谬误
日常执行中次要有同步谬误、语法错误、一般异步工作谬误、Promise 工作谬误、async 工作谬误 5 种常见的异样谬误。
资源加载谬误
次要有图片、script、css、font 等资源的加载谬误问题。
谬误捕捉
try…catch
作为一个优良的程序员,首先咱们能想到的肯定是 try…catch,那么咱们间接上代码:
因为资源加载标签必定不能在代码块中执行,因而资源加载谬误必定无奈捕捉。
基于上图后果,咱们能够小结一下 try…catch 的解决能力:
- 能捕捉包裹体内的同步执行谬误。
- 不能捕捉语法错误。
- 不能捕捉异步工作谬误。
- 不能捕捉 Promise 工作谬误。
- 不能捕捉资源加载谬误。
window.onerror
咱们浏览器在 window 对象上还自带了一个 onerror 的办法
须要额定留神:跨域脚本加载谬误只有一个“Script error”,并不能获取到错误信息。能够通过在 <script> 标签上增加“crossorigin”属性来解决这个问题。
基于上图后果,咱们再小结一下 window.onerror 的解决能力:
- 能捕捉所有同步执行谬误。
- 不能捕捉语法错误。
- 能捕捉一般异步工作谬误。
- 不能捕捉 Promise 工作谬误。
- 不能捕捉 async 工作谬误。
- 不能捕捉资源加载谬误。
window.addEventListener(‘error’)
在 Web 页面上咱们能够监听绝大多数事件,当然也包含谬误事件,咱们从字面意思上浅了解咱们能够认为与 onerror 差不多,然而实际上它们俩的体现还是有一点区别,这里咱们给出 addEventListener 额定能捕捉的谬误,其余与 onerror 基本一致:
这里要额定留神的是:如果是在 js 代码中 new Image() 后加载呈现的谬误是无奈捕捉的。
相比 window.onerror,通过 window.addEventListener 的形式咱们能够捕捉资源加载的谬误。
window.addEventListener(‘unhandledrejection’)
方才咱们介绍了 3 种常见的谬误捕捉形式,但都不能捕捉 Promise 工作的谬误,这里有人会说了,Promise 不是能够本人 catch 吗?是的,然而我置信大多数状况下咱们的开发同学可能并不会为每一个 Promise 写一个 catch,或者可能呈现漏写的状况。Js 为咱们筹备了一个“兜底计划”: unhandledrejection 事件监听。它会在 Promise 被 reject(抛错)且没有被 catch 的时候触发。上面上例子:
当然如果咱们将没有 catch 的 Promise 放在 async 中去执行,unhandledrejection 事件监听也能捕捉到。所以 async 工作谬误 unhandledrejection 事件监听也是能够反对捕捉的。
题外话:咱们能够看到这个事件的名称叫做 unhandledrejection,作为一个英语词法敏锐的程序员,霎时想到,有没有叫 handledrejection 的事件呢,如果有,咱们是不是能够猜想作用刚好是相同呢?还真有!并且正如咱们所猜想的,它是在 Promise 的 reject 做了解决(catch)后触发!这里咱们就不开展议论,有趣味的同学能够钻研一下。
回归正题,咱们通过这么多例子测试了 4 种捕捉谬误的形式,总结失去下表:
那么咱们察看这个表格,首先能够看到语法错误,4 种形式都不能捕捉,然而咱们个别认为语法错误不应该在执行阶段才发现,在咱们的编译以及测试环节就能够查看出,所以咱们不思考将其捕捉。那么其余的异样谬误咱们发现通过 addEventListener(‘onerror’) + addEventListener(‘unhandledrejection’) 的形式恰好可能笼罩 5 种异样谬误的捕捉,一起来实现一下:
把 Promise 及 async 工作中的谬误捕捉后用同步的逻辑抛出即可让 onerror 精确捕捉到。
如此,咱们就能够将咱们 Web 中大部分的异样问题进行精确捕捉。
接下来咱们看看如何将谬误问题上报至咱们的服务器进行汇总。
数据上报
XMLHttpRequest
咱们想要将数据传回服务器,最通用的形式当然就是 ajax 申请,通过浏览器的 XMLHttpRequest(这里咱们不探讨 IE)的 send 办法,发送 post 申请数据给服务端,这里咱们不再给出实现。
其毛病也很显著:
- 有严格的跨域限度、携带 cookie 问题。
- 上报申请可能会阻塞业务。
- 申请容易失落(被浏览器强制 cancel)。
Image
因为浏览器对资源文件的区别对待,为了解决下面的几个问题,咱们能够通过创立一个 1 ×1 大小的图片进行异步加载的形式来上报。图片人造可跨域,又能兼容所有的浏览器,而 js 和 css 等其余资源文件则可能呈现平安拦挡和跨域加载问题。
但因为是一个 get 申请,上报的数据量在不同的浏览器下下限不统一(2kb-8kb),这就可能呈现超出长度限度而无奈上报残缺数据的状况。因而,图片上报也是一个“不平安”的形式。
SendBeacon
这个办法天生就是为了数据统计而设计的,它解决了 XMLHttpRequest 和图片上报的绝大部分弊病:没有跨域问题、不阻塞业务,甚至能在页面 unload 阶段持续发送数据,完满地解决了一般申请在 unload 阶段被 cancel 导致丢数据的问题,惟一的问题就是 IE 并不反对。
调用形式也非常简单,相似咱们发送 post 申请:
这里须要留神的是,sendBeacon 并不像 XMLHttpRequest 一样能够间接指定 Content-Type,且不反对 application/json 等常见格局。data 的数据类型必须是 ArrayBufferView 或 Blob, DOMString 或者 FormData 类型的。这里给出 Blob 类型的示例。
小结
基于以上 3 种上报形式,咱们能够根本总结出,上报数据倡议优先应用 sendBeacon 的形式,不反对的浏览器(例如 IE)则降级应用图片上报,尽量避免间接应用 XMLHttpRequest 进行上报。
结语
目前你尽管 GrowingIO Web SDK 当初并没有对这些异样谬误做残缺的收集(因为咱们的产品重点不在这),然而咱们有须要的用户能够本人实现谬误捕捉的逻辑并应用 SDK 的埋点办法进行上报。
另外,咱们正在 Web SDK 上进行架构演进且行将实现,创新性地提供了客户自定义插件的能力!后续您能够尝试通过 SDK 提供的插件能力,自行开发一个谬误收集的插件(甚至是性能采集插件),配合 SDK 原有性能就能实现业务经营数据和开发所需的谬误、性能数据的采集!敬请期待!
以上就是咱们明天为大家分享的 Web 利用 Js 异样谬误收集的内容。
参考文献:
*https://developer.mozilla.org…
https://developer.mozilla.org…
https://developer.mozilla.org…
https://developer.mozilla.org…
https://developer.mozilla.org…*