可能由于网络、浏览器问题、缓存等原因,可能导致线上执行 js 的时候与开发环境并不一样,会抛出异常。js 异常基本上是前端开发工程师的家常便饭。如何记录,并使用它,却很少人关注。最近在考虑一个想法,基本上涉及到两步:收集和使用。
一、收集
对于 error 收集这一块,还是比较方便的,因为在各浏览器中都有一个接口:window.onerror:
window.onerror = function(errorMessage, scriptURL, lineNumber) {
alert(errorMessage, scriptURL, lineNumber)
} 甚至中提供了 Stack Trace,比如在 try/catch 中还提供了 e.stack(各个浏览器不同,可以使用 eriwen/javascript-stacktrace 这个兼容库),试一下下面这段代码:
try {
fn()
} catch(e) {
alert(e.stack)
} 所以收集这些错误还是比较方便的,这里需要注意的事,使用 window.addEventListener('error', callback, isBubble) 中 callback 的第一个参数并不是 event,而是一个 Error object。这样的话,为了方便,使用 window.onerror 是一个不错的选择,但通过 dot 操作符监听的事件是可以重载的,并且这段监听脚本理论上是放在所有 js 最前面的,所以需要考虑其中的风险。
立即学习“Java免费学习笔记(深入)”;
二、使用
之前在支付宝的时候,线上 js 报错会变成一个邮件,发给前端开发 team,每个人自己认领、解决。其实这是一个不错的选择,也解决了最基本的问题:立即响应,修掉。不过也存在着一个问题,如果避免同样的错误?我的初步想法是这样的:
以 URL 为单元,记录同一个页面的报错:方便统一解决
记录错误包括:Page URL, User Agent, Script URL, Error Message 和 Line Number
每个错误解决后,都可以在一个地方写解决方案,看到的人可以评论、加分,最终会存档起来,作为一个知识库,并用有方便的 api 可以使用这些知识库的内容
在开发的时候,相同页面 window.onerror 的时候,通过插件,分析 Error Message 识别出类型,加上 URL 的判断,给予开发者提醒前人犯过的错误
开发者可以订阅知识库上某些标签,自动接收邮件(当然也可以根据文件注释、mapping 等方式做更好的配对)
为什么这样做?主要是为了解决下面的一些问题:
形成知识库,开发者可以从中得到学习,特别是新人
工具保证效率的提升和避免重复错误重复解决
订阅保证通知更具针对性
三、注意点
1. 收集的时候使用 POST 发送
有时候 Error Message 可能会比较长,而浏览器的 URL 长度是有限制的,如果存的错误不多的话,可以考虑用 GET 发送,但通常来说 POST 可以把所有数据都发送到后台。
本书将PHP开发与MySQL应用相结合,分别对PHP和MySQL做了深入浅出的分析,不仅介绍PHP和MySQL的一般概念,而且对PHP和MySQL的Web应用做了较全面的阐述,并包括几个经典且实用的例子。 本书是第4版,经过了全面的更新、重写和扩展,包括PHP5.3最新改进的特性(例如,更好的错误和异常处理),MySQL的存储过程和存储引擎,Ajax技术与Web2.0以及Web应用需要注意的安全
400
2. 何时发送数据
建议在触发 onerror 的时候发送。在第一次有这个想法的时候,尝试着在 onbeforeonload 的时候发送,但 POST 请求还没 open 就已经被浏览器中断了。
3. 存于数据库以哪个作为索引比较好?
通常来说以 URL 可能会比较适合多数网站。但像百姓网、淘宝等 UGC 比较多的网站,可能需要变通一下以记录 URL。毕竟不同帖子不同 URL 都是同一套代码。
那以 Error 作为索引呢?其实无论是那种,看自己需求选择吧。
4. 是否记录所有错误
这个也比较合适根据需求来看。百姓网有各种乱七八糟的报错可能都是来自到 baidu / Google 的 ad 外链。
四、结语
目前初步实现了一个收集的工具(sofish/stacktrace.js)和存储方式(以 URL 为索引),是否继续,还需要时间和进一步考虑,先发出来,抛砖引玉。
五、附录
<?php
$url = new Url();
$page = $url->post('page');
if(!$page) return;
class ErrorTrace extends MongoData {
// MongoData 中没有,区别
public function findOne($obj) {
return $this->connection->findOne($obj);
}
};
$store = new ErrorTrace();
$fields = array(
'url' => $url->post('url'),
'message' => $url->post('message'),
'line' => $url->post('line'),
'ua' => $url->post('ua'),
);
$index = array('page' => $page);
$hash = md5(json_encode($fields));
// 不重复记录一个错误,所有错误记录在同一个 URL 下
if($field = $store->findOne($index)) {
if(isset($field[$hash])) return;
return $store->setAttr(new Query('page', $page), $hash, $fields);
}
$store->page = $page;
$store->$hash = $fields;
$store->save();
?> This Gist brought to you by GitHub.
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号