背景
家喻户晓,简直没有一个开发者可能做到开发时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
因为浏览器对资源文件的区别对待,为了解决下面的几个问题,咱们能够通过创立一个1x1大小的图片进行异步加载的形式来上报。图片人造可跨域,又能兼容所有的浏览器,而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...*