前言

这篇文章想要说明的是

  1. JavaScript 异常的概念
  2. JavaScript 异常的处理
  3. JavaScript 异常的收集
  4. JavaScript 异常的分析(后面再更新)

前端工程师都知道,JavaScript 拥有基本的异常处理方法,但是一般前端工程师都不会处理异常。其实情有可原,对于普通网站来说,异常是非常可控的,基本可以刷新页面就解决问题,运行环境+代码运行也很少带来异常。但是对于业务富集的webApp/大型组件来说,没有异常处理会是异常灾难。无论在用户使用场景或者在开发/调试 作为出发点,异常处理都是非常必要的
异常处理非常重要,它可以提高程序健壮性,对于其他软件开发来说,健壮性是非常重要的一项指标。

这里会引用一篇实用性很强的文章,在错误日志捕抓/收集提供了一些实用的方法,这里提供文章传送门

JavaScript 异常的概念

异常的出现

当你的JavaScript语法,错误的调用方式,变量没有定义,等等这些都会出现错误,而这种异常JavaScript会抛给开发者。我们能在控制到看到异常的具体信息,包括异常类型异常所在的JS文件异常所在的行数异常的堆栈信息,这些异常信息都是让我们能更迅速的找到异常并且解决。

异常的载体

异常通过Error对象表达出来,对象的属性包括:
来源Mozilla官方文档

Microsoft

Error.prototype.description

Error.prototype.number

Mozilla

Error.prototype.fileName // 出现异常的文件路径

Error.prototype.lineNumber //发生异常的js文件行数

Error.prototype.columnNumber //发生异常的js文件列数

Error.prototype.stack // 异常的堆栈信息

Error对象的子类
EvalError
InternalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError


我们通过 throw 关键字能向浏览器抛出一个异常对象

  throw new Error('Whoops!'); //Error其他z

这里不对Error 属性以及原理讨论,有兴趣的同学可以去Mozilla,或者W3官方查阅相关文档。

JavaScript 异常的处理

编程语言都会提供处理异常的方法,就是JavaScript就是 try catch 语句,通过try方法捕抓异常,捕抓到异常后会退出try 代码块(即{//code}),然后执行catch语句,catch有一个Error对象的实参,在catch代码块能引用这个Error对象。

捕抓错误的语句:

try{//your code
}catch(e){//while raise a error ,will exc this code
}
catch(e){//while raise a error,and pre catch has beed run  ,will exc this code
}
catch(e){//while raise a error,and pre catch has beed run  ,will exc this code
}final{//whether raise a error, this code will be run
}

try语句允许我们定义在执行时进行错误测试的代码块。
catch 语句允许我们定义当 try 代码块发生错误时,所执行的代码块。
finally 语句在 try 和 catch 之后无论有无异常都会执行。
注意: catchfinally 语句都是可选的,但你在使用 try 语句时必须至少使用一个。

JavaScript 异常的收集

对于后端来说错误日志收集是个老生常谈的话题,在前端还是相对听的少,比较集成服务器的构建,日志分析等等并不是前端必需掌握的技能。
捕抓错误
对于web前端来说JavaScript的异常还是相对好捕抓的,异常出现以后,会触发错误事件传递给window对象, 可以用 window.onerror = function(){}来捕抓页面上每一个错误,所以捕抓错误很简单。
错误信息
我们要把我们需要的错误信息,post去我们的日志记录服务器那里,要做的:

  1. 整理需要记录的信息(包括,error属性,userAgent等等)
  2. error兼容性处理,不同浏览器error对象的属性会有差异,要做兼容处理
  3. 序列化消息,日志会以字符串的形式上传,属性需要做序列化处理
  4. 属性丢失,我们会想要收集些比较有用的信息包括:错误类型(name)、错误消息(message)、脚本文件地址(script)、行号(line)、列号(column)、堆栈跟踪(stack)。如果一个异常是通过 try-catch 捕获到的,这些信息都在 Error 对象上(主流浏览器都支持)。但如果是通过 window.onerror 捕获到的,我们都知道这个事件函数只有 3 个参数,所以这 3 个参数以外的信息就丢失了。

注意不要耍小聪明使用 window.addEventListener 或 window.attachEvent 的形式去监听 window.onerror。很多浏览器只实现了 window.onerror,或者是只有 window.onerror 的实现是标准的。考虑到标准草案定义的也是 window.onerror,我们使用 window.onerror 就好了。

实践与分析(更新2016-12-12)

基于大神的实现经验,这段时间也搭起来自己的服务器来收集日志总结一下这段时间的遇到的问题,以及记录自己异常分析思路。

前提:
首先说明项目技术栈。项目技术栈毕竟老旧,jquery+require,项目看重seo,当时也没有能力搭起node-server 做服务端渲染,所以项目还是以传统网站的实现方式实现。

遇到的问题 (update on 2017年1月9日,旧内容会用斜体注释):

js文件跨域

把资源放到cdn是一个非常常见的 优化方案,但是当遇到require问题就来了。一般跨域在script里面添加 crossorigin 属性就可以了,但是由于资源加载管理,放在require里面,所以我的解决方案是修改require 源码,在创建script标签的时候添加 crossorigin属性。

修改的源码

req.load = function (context, moduleName, url) {var config = (context && context.config) || {},node;if (isBrowser) {//In the browser so use a script tagnode = req.createNode(config, moduleName, url);node.setAttribute('data-requirecontext', context.contextName);node.setAttribute('data-requiremodule', moduleName);node.crossOrigin="anonymous" //添加跨域头

但是问题并不能完全解决,ie浏览器上script标签没有实现 crossOrigin 属性,ie上的异常还是没办法收录。
由于reuqire 完全掌握js文件加载,所以我们也没有办法使用大神解决方案来解决我的问题。陷入绝望ing


update on 2017年1月9日

关于 script error 的解决方案

由于看到了大神的一些经验总结,在文章当中找到一些相关的资料,这里记录 script error 原因&解决方案;

出现 script error 的场景和条件

  1. 通过window.onerror 注册监听脚本错误事件
  2. 浏览器:Firefox,Chrome,Safari,IE7+(*)
  3. 页面内使用了script 标签引入,非同源的资源,且发生了脚本错误

本质上是出于安全考虑。因为 script 标签引入文件内容的时候是忽略文件本身的MIME声明,且是允许跨域请求的。这里如果不屏蔽掉跨域情况下的错误信息,很可能会给黑客提供一个攻击通道。

webkit 处理源码

//http://trac.webkit.org/browser/trunk/Source/WebCore/dom/ScriptExecutionContext.cpp#L347bool ScriptExecutionContext::sanitizeScriptError(String& errorMessage,int& lineNumber,int& columnNumber,String& sourceURL,CachedScript* cachedScript){URL targetURL = completeURL(sourceURL);if (securityOrigin()->canRequest(targetURL) ||(cachedScript && cachedScript->passesAccessControlCheck(*securityOrigin())))

怎么解决 Script error ?

1. 添加同源策略

在脚本文件的 HTTP response header 中设置 CORS
比如: Access-Control-Allow-Origin: http://yuncaijing.com
在页面的 script 标签中设置 crossorigin 属性
比如:<script src="http://7.url.cn/index.js" crossorigin></script>

CORS header 和 crossorigin 取值问题

  1. anonymous(默认)
    CORS 不等于 origin, 不能带 cookie
  2. use-credentials
    Access-Control-Allow-Credentials: true
    CORS 不能设置为 *,能带 cookie
    CORS 不等于 origin,js 直接不加载

关于CORS header 和 crossorigin的资料

2. 使用try - catch (通用不丢失错误信息方法)
  1. 每个方法都包裹上 try catch
  2. 对主要入口方法进行try catch

!!!!只需要对异步模块和业务主入口添加 try catch

  1. setTimeout 和 setInterval
  2. 事件绑定
  3. ajax callback
  4. define 和 require
  5. 业务主入口

补充问题

通过 XHR 获取脚本资源, 通过 script 标签 innerText 插入到页面,到导致会丢失错误的行号列号和文件名等信息


资源合并压缩

资源压缩合并也是非常常见的优化手段。压缩合并后的js文件完全是没法阅读的,想找到异常的位置,需要根据堆栈信息的行列号,到压缩合并后的js文件中 匹配,这个debug过程相对不智能,
//解决方案 以后找到再更新

收集的信息

我的数据包字段是这样的

{host:'',//域path:'',//url 路径file:'',//异常文件stack:'',//异常堆栈信息ua:'',//经过前端处理的ua信息 (xx系统 xx浏览器 xxx版本)userAgent:'',//浏览器ua字段
}

这里收集起来最有用的就是ua,和stack。这两个是反映真实用户的终端设备,和异常的信息的,这两个信息对于找到bug的原因有十分大的帮助。

这里建议在浏览器中判断ua的类型,在服务器中光靠userAgent字段是没办法真实的判断浏览器环境的

分析

这里简单说一下分析思路。

日志收集过来,所以首先第一步明确我们想从这堆信息中获得什么信息。

1. 系统发生异常的概率
2. 按照某个周期排列某种异常(可以是总数 , 可以是某种异常,可以是异常发生概率),观察趋势。
3. 某个html文件(某个url,或者某种url)发生错误的占比。
4. 某个js文件发生异常占比
5. 某个错误信息出现的次数
6. 某个异常,会有多少种异常

以上几点都会以图表形式展示,我分析的目标主要侧重趋势,图表能直观反映某个状态的严重状况,反映编码质量/测试质量上升还是下降。

参考资料:
Mozilla官方文档
大神实践总结

JavaScript 异常处理及异常收集相关推荐

  1. Atitit.js javascript异常处理机制与java异常的转换 多重catc hDWR 环境 .js exception process Vob7...

    Atitit.js javascript异常处理机制与java异常的转换 多重catc hDWR 环境 .js exception process Vob7 1. 1. javascript异常处理机 ...

  2. JavaScript 异常处理

    异常处理概述在代码的运行过程中,错误是不可避免的,总的来说,错误发生于两种情况:一是程序内部的逻辑或者语法错误,二是运行环境或者用户输入中不可预知的数据造成的错误.对于前者,就称之为错误(error) ...

  3. JavaScript异常处理

    异常处理概述在代码的运行过程中,错误是不可避免的,总的来说,错误发生于两种情况:一是程序内部的 逻辑或者语法错误,二是运行环境或者用户输入中不可预知的数据造成的错误.对于前者,就称之为错误(error ...

  4. JavaScript错误与异常

    JavaScript错误与异常 下面是对JavaScript错误与异常的整理,希望可以帮助到有需要的小伙伴. 1.错误与异常是什么 错误,指程序中的非正常运行状态,在其它编程语言中称为"异常 ...

  5. JavaScript——异常处理

    JavaScript--异常处理 1. throw抛异常 异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法继续运行. function counter(x, ...

  6. 【嵌入式开发】ARM 异常向量表 ( 异常概念 | 异常处理流程 | 异常向量 | 汇编代码 )

    一. 异常向量表 1. 异常相关概念 (1) 异常 (2) 异常类型简介 2. 异常处理 (1) 异常处理 二. 异常向量表代码编写 1. 初始化异常向量表模块代码 2. 链接器脚本 3. Makef ...

  7. Java异常处理及异常机制介绍

    Java异常处理及异常机制介绍 当出现程序无法控制的外部环境问题(用户提供的文件不存在,文件内容损坏,网络不可用...)时,JAVA就会用异常对象来描述. JAVA中用2种方法处理异常: 1.在发生异 ...

  8. java 异常处理发生异常_处理Java中的异常

    java 异常处理发生异常 每个程序员都希望编写一个完美的程序. 也就是说,程序运行时没有任何障碍. 好吧,如果希望是马,乞g就会骑. 除了程序员的所有愿望之外,有时还会发生无法预料的情况. 在Jav ...

  9. 复习Java异常处理_异常分类_自定义异常_线程初步了解

    复习Java异常处理_异常分类_自定义异常_线程 主要内容 异常.线程 教学目标 第一章 异常 1.1 异常概念 异常,就是不正常的意思.在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点 ...

最新文章

  1. linux卸载rpm包
  2. ubuntu下磁道坏区的检测与修复
  3. python histo 改变 bins 大小_子批次大小python
  4. 产品经理,如何建立自己独特的产品观?(转)
  5. eeprom 数据偶尔变成ff_关于水电站冗余配置下监控系统下发调节令偶尔不动作的案例分析...
  6. redis实战_Redis实战(7)-SortedSet实战之认识有序集合(命令行与代码实战)
  7. SharePoint 2010 自定义Ribbon实现文档批量下载为Zip文件
  8. java.io.IOException: output.properties data exceeds its limit [2048] hue的调度
  9. jcr多久更新一次_科学网—你知道吗,SCI影响因子数据在7月又有更新了 - LetPub编辑的博文...
  10. UTD2202C示波器如何显示峰峰值
  11. 数字资产期权新手入门手册 | TokenInsight
  12. win10右键卡顿原因_如何解决Win10桌面右键一直卡顿转圈的问题?
  13. 16.【linux驱动】spi驱动TFT液晶屏
  14. 关于传递函数的频率响应和低通滤波器
  15. 使用kermit串口工具时出现 /dev/ttyS0 is not a terminal device 错误
  16. 使用Galen进行Responsive Web测试四部曲
  17. Tensorflow与keras学习 (3)——循环神经网络RNN
  18. 使用awk处理多行fasta文件拆分为单个fasta文件,并去掉后缀^M
  19. python如何使用gpu加速_如何用云端 GPU 为你的 Python 深度学习加速?
  20. 高数量类别特征(high-cardinality categorical attributes)的预处理方法

热门文章

  1. Android中使用Drawable绘制横竖虚线
  2. Java外包是如何进入阿里的?源码+原理+手写框架
  3. ArcGIS应用(一)提取遥感影像各波段值
  4. c语言黑匡程序,2020年新版C语言实用程序设计100例流程图.docx
  5. python读取图片信息gps位置
  6. HTML中 :after和:before的作用及使用方法(转)
  7. 包装用铝盖的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  8. vsphereClient虚拟化平台无法进入登录界面
  9. 区块链房屋溯源项目搭建教程
  10. 74192减法计数器原理图_趣味学习三菱PLC之定时器和计数器