**
javascript错误处理
**
由于javascript本身是动态语言,而且没有固定的开发工具,因此他普遍认为是最难以调试的语言,在ECMAScript3新增了try-catch和throw以及一些错误类型,让开发人员能适当的处理错误,紧接着web浏览器也出现了一些javascript的调试程序和工具
错误类型:
执行代码期间可能会发生的错误类型有多种,每种错误都有对应的错误类型,如下
- Error 普通错误类型
- EvalError 类型的错误一般使用了eval函数而发生的异常
- RangeError 类型的错误一般在数值超出相应的范围时触发
- ReferenceError 这种比较常见 访问的变量不存在
- SyntaxError 这种一般很少见
- TypeError 一般是保存变量存在其他的类型
- URLError 在使用encodeURL或decodeURL函数时,url格式不正确会报这个URLError错误
处理错误
我们在项目中最常见的就是使用try-catch来处理
try{.
// 一般是我们的逻辑代码,可能会导致错误的代码}catch{
// 在错误发生时会在这里进行处理
}// 注意catch后面还有一个finally子句
function testFinally(){try{return 3}catch{. return 2}finally{reutrn 1}
}
// finally子句他的机制是不管try或catch执不执行,最后finally都会去执行 所以这段代码// 最后返回的结果是 1 而不是 2
抛出错误
与tru-catch语句相配合的又一个throw操作符,用于随时抛出自定义错误,抛出错误时,必须要赋值,至于这个值是什么类,是不做要求的。在执行throw操作符时,代码会立即停止执行,仅当有try-catch语句捕获到被抛出的值时,才会继续执行
throw 1234
throw [1,2,3,4]
throw true
....
一般情况下可以通过某种内置错误模拟浏览器的错误,每种错误类型只需要接受一个参数
throw new Error('something bad happend')
throw new TypeError('what type of variable do you take me for ?')
...
还可以创建一个自定义错误类型
function CustomerError(message){this.name = 'CustomError'this.message = message
}
CustomerError.prototype = new Error()
throw new CustomerError ('my message')
错误事件
任何没有通过tru-catch处理的错误都会触发window对象的error事件,而且这事件对于chrome firefox IE 都是支持的。具体方法如下:
// onerror接受三个参数 错误消息 错误所在的url 某个文本第多少行发生的错误,对于我们现在通过vue 或react框架大包之后我们一般只有message这个参数对我们开发人员有人,其他的可能意义不大,这里提一下如果要定位到线上具体的文件的错误可以使用sourceMap来定位,这里就不多废话了。
window.onerror = function (message,url,line){console.log(message)
}
注意常见的错误类型
1.数据转换错误
我们使用的非常多的 == 和 != 还有 === 等这些需要在开发的过程中注意
5 == ‘5’ // true
5 === ‘5’ // false
1 == true // true
1 === true // false
...// 这个看似没有问题,但是一旦出入的不是数字,可能程序就直接挂了
function concat (str1,str2,str3){let result = str1 + str2if(str3){result += str3}return result
}再比如数据类型的错误:
function resverseSort(values){if(values){ // 这是只要有值过来就过了 values.sort()}if(values != null) { // 不靠谱 values.sort()} if(typeof value.sort == 'function') { // 不靠谱 values.sort()} if(values instanceof Array) { // 这种是比较稳妥的 values.sort()}
}// 通信错误
一般是在与后端对接的时候URL的格式不正确或者发送的数据有问题造成的。
对于URL地址,没有使用encodeURLComponent()造成的问题
可以写一个简单的函数 function addQueryStringArg(url,name,value){if(url.indexOf("?") == -1){url+= "?"}else{url += "&"}url += encodeURLComponent(name) + '=' + encodeURLComponent(value)
}
const url = 'http://www.some.com'
let newUrl = addQueryStringArg(url,'redir','http://www.something.com?a=1&b=2')
把错误记录到服务器
要记录js的错误记录系统,先要在服务器上创建一个页面,或者一个服务入口,再来处理错误数据
这个所有浏览器都支持,且能够跨域,可以处理多台服务器的记录。
function logError(sev,msg){var img = new Image()img.src = "log.php?sev=" + encodeURLComponent(sev) + "&msg="+ encodeURLComponent(msg)
}一般如果想要记录,只要出现try-catch的语句可以在catch里面调用这个方法
try{
}catch(err){
logError('nonfatal' , '某某错误失败:'+ err.message)
}