错误处理和调试

21.1 浏览器错误报告

21.2 错误处理

21.2.1 try/catch 语句

  1. 错误类型
    代码执行过程中会发生各种类型的错误。每种类型都会对应一个错误发生时抛出的错误对象。
    ECMA-262 定义了以下 8 种错误类型:
     Error
     InternalError
     EvalError
     RangeError
     ReferenceError
     SyntaxError
     TypeError
     URIError
    Error 是基类型,其他错误类型继承该类型。因此,所有错误类型都共享相同的属性(所有错误对象上的方法都是这个默认类型定义的方法)。浏览器很少会抛出 Error 类型的错误,该类型主要用于开
    发者抛出自定义错误。
    InternalError 类型的错误会在底层 JavaScript 引擎抛出异常时由浏览器抛出。例如,递归过多导
    致了栈溢出。这个类型并不是代码中通常要处理的错误,如果真发生了这种错误,很可能代码哪里弄错
    了或者有危险了。
    EvalError 类型的错误会在使用 eval()函数发生异常时抛出。ECMA-262 规定,“如果 eval 属性
    没有被直接调用(即没有将其名称作为一个 Identifier ,也就是 CallExpression 中 的
    MemberExpression),或者如果 eval 属性被赋值”,就会抛出该错误。基本上,只要不把 eval()当
    成函数调用就会报告该错误:
    new eval(); // 抛出 EvalError
    eval = foo; // 抛出 EvalError
    实践中,浏览器不会总抛出 EvalError。Firefox 和 IE 在上面第一种情况下抛出 TypeError,在
    第二种情况下抛出 EvalError。为此,再加上代码中不大可能这样使用 eval(),因此几乎遇不到这种
    错误。
    RangeError 错误会在数值越界时抛出。例如,定义数组时如果设置了并不支持的长度,如-20 或
    Number.MAX_VALUE,就会报告该错误:
    let items1 = new Array(-20); // 抛出 RangeError
    let items2 = new Array(Number.MAX_VALUE); // 抛出 RangeError
    RangeError 在 JavaScript 中发生得不多。
    ReferenceError 会在找不到对象时发生。(这就是著名的"object expected"浏览器错误的原
    因。)这种错误经常是由访问不存在的变量而导致的,比如:
    let obj = x; // 在 x 没有声明时会抛出 ReferenceError
    SyntaxError 经常在给 eval()传入的字符串包含 JavaScript 语法错误时发生,比如:
    eval(“a ++ b”); // 抛出 SyntaxError
    在 eval()外部,很少会用到 SyntaxError。这是因为 JavaScript 代码中的语法错误会导致代码无
    法执行。
    TypeError 在 JavaScript 中很常见,主要发生在变量不是预期类型,或者访问不存在的方法时。很
    多原因可能导致这种错误,尤其是在使用类型特定的操作而变量类型不对时。下面是几个例子:
    let o = new 10; // 抛出 TypeError
    console.log(“name” in true); // 抛出 TypeError
    Function.prototype.toString.call(“name”); // 抛出 TypeError
    在给函数传参数之前没有验证其类型的情况下,类型错误频繁发生。
    最后一种错误类型是 URIError,只会在使用 encodeURI()或 decodeURI()但传入了格式错误的
    URI 时发生。这个错误恐怕是 JavaScript 中难得一见的错误了,因为上面这两个函数非常稳健。
    不同的错误类型可用于为异常提供更多信息,以便实现适当的错误处理逻辑。在 try/catch 语句
    的 catch 块中,可以使用 instanceof 操作符确定错误的类型,比如:
    try {
    someFunction();
    } catch (error){
    if (error instanceof TypeError){

21.2.7 把错误记录到服务器中

Web 应用程序开发中的一个常见做法是建立中心化的错误日志存储和跟踪系统。数据库和服务器错
误正常写到日志中并按照常用 API 加以分类。对复杂的 Web 应用程序而言,最好也把 JavaScript 错误发
送回服务器记录下来。这样做可以把错误记录到与服务器相同的系统,只要把它们归类到前端错误即可。
使用相同的系统可以进行相同的分析,而不用考虑错误来源。
要建立 JavaScript 错误日志系统,首先需要在服务器上有页面或入口可以处理错误数据。该页面只
要从查询字符串中取得错误数据,然后把它们保存到错误日志中即可。比如,该页面可以使用如下代码:
function logError(sev, msg) {
let img = new Image(),
encodedSev = encodeURIComponent(sev),
encodedMsg = encodeURIComponent(msg);
img.src = ‘log.php?sev=KaTeX parse error: Expected 'EOF', got '&' at position 13: {encodedSev}&̲msg={encodedMsg}’;
}
logError()函数接收两个参数:严重程度和错误消息。严重程度可以是数值或字符串,具体取决
于使用的日志系统。这里使用 Image 对象发送请求主要是从灵活性方面考虑的。
 所有浏览器都支持 Image 对象,即使不支持 XMLHttpRequest 对象也一样。
 不受跨域规则限制。通常,接收错误消息的应该是多个服务器中的一个,而 XMLHttpRequest
此时就比较麻烦。
 记录错误的过程很少出错。大多数 Ajax 通信借助 JavaScript 库的包装来处理。如果这个库本身
出错,而你又要利用它记录错误,那么显然错误消息永远不会发给服务器。
只要是使用 try/catch 语句的地方,都可以把相关错误记录下来。下面是一个例子:
for (let mod of mods){
try {
mod.init();
} catch (ex){
logError(“nonfatal”, ‘Module init failed: ${ex.message}’);
}
}
在这个例子中,模块初始化失败就会调用 logError()函数。第一个参数是表示错误严重程度的
“nonfatal”,第二个参数在上下文信息后面追加了 JavaScript 错误消息。记录到服务器的错误消息应
该包含尽量多的上下文信息,以便找出错误的确切原因

猜你喜欢

转载自blog.csdn.net/cs18335818140/article/details/113828753