目录
浏览器报告的错误
错误处理
try-catch语句
try{
// 可能会导致错误的代码
} catch(error){
// 在错误发生时怎么处理
}
try {
window.someNonexistentFunction();
} catch (error){
alert(error.message);
}
finally 子句
只要代码中包含 finally 子句,则无论 try 或 catch 语句块中包含什么代码——甚至 return 语句,都不会阻止 finally 子句的执行。
function testFinally(){
try {
return 2;
} catch (error){
return 1;
} finally {
return 0;
}
}
错误类型
ECMA-262 定义了下列 7 种错误类型:Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError。
Error 是基类型,其他错误类型都继承自该类型。
合理使用 try-catch
使用 try-catch 最适合处理那些我们无法控制的错误。在明明白白地知道自己的代码会发生错误时,再使用 try-catch 语句就不太合适了。
抛出错误
在遇到 throw 操作符时,代码会立即停止执行。仅当有 try-catch 语句捕获到被抛出的值时,代码才会继续执行。
throw new SyntaxError("I don’t like your syntax.");
throw new TypeError("What type of variable do you take me for?");
throw new RangeError("Sorry, you just don’t have the range.");
throw new EvalError("That doesn’t evaluate.");
throw new URIError("Uri, is that you?");
throw new ReferenceError("You didn’t cite your references properly.");
//创建自定义错误类型
function CustomError(message){
this.name = "CustomError";
this.message = message;
}
CustomError.prototype = new Error();
throw new CustomError("My message");
抛出错误的时机
应该在出现某种特定的已知错误条件,导致函数无法正常执行时抛出错误。
function process(values){
if (!(values instanceof Array)){
throw new Error("process(): Argument must be an array.");
}
values.sort();
for (var i=0, len=values.length; i < len; i++){
if (values[i] > 100){
return values[i];
}
}
return -1;
}
抛出错误与使用 try-catch
捕获错误的目的在于避免浏览器以默认方式处理它们;而抛出错误的目的在于提供错误发生具体原因的消息。
错误(error)事件
任何没有通过 try-catch 处理的错误都会触发 window 对象的 error 事件。
window.onerror = function(message, url, line){
alert(message);
};
图像也支持 error 事件。只要图像的 src 特性中的 URL 不能返回可以被识别的图像格式,就会触发 error 事件。
var image = new Image();
EventUtil.addHandler(image, "load", function(event){
alert("Image loaded!");
});
EventUtil.addHandler(image, "error", function(event){
alert("Image not loaded!");
});
image.src = "smilex.gif"; //指定不存在的文件
处理错误的策略
所谓 Web 应用程序的错误处理策略仅限于服务器端。在谈到错误与错误处理时,通常要考虑很多方面,涉及一些工具,例如记录和监控系统。这些工具的用途在于分析错误模式,追查错误原因,同时帮助确定错误会影响到多少用户。
常见的错误类型
类型转换错误
类型转换错误发生在使用某个操作符,或者使用其他可能会自动转换值的数据类型的语言结构时。在使用相等(==)和不相等(!=)操作符,或者在 if、 for 及 while 等流控制语句中使用非布尔值时,最常发生类型转换错误。
数据类型错误
JavaScript 是松散类型的,也就是说,在使用变量和函数参数之前,不会对它们进行比较以确保它们的数据类型正确。为了保证不会发生数据类型错误,只能依靠开发人员编写适当的数据类型检测代码。在将预料之外的值传递给函数的情况下,最容易发生数据类型错误。
通信错误
第一种通信错误与格式不正确的 URL 或发送的数据有关。最常见的问题是在将数据发送给服务器之前,没有使用 encodeURIComponent()对数据进行编码。
另外,在服务器响应的数据不正确时,也会发生通信错误。
区分致命错误和非致命错误
非致命错误:不影响用户的主要任务;只影响页面的一部分;可以恢复;重复相同操作可以消除错误。
致命错误: 应用程序根本无法继续运行; 错误明显影响到了用户的主要操作; 会导致其他连带错误。
把错误记录到服务器
调试技术
将消息记录到控制台
对 IE8、 Firefox、 Chrome 和 Safari 来说,可以通过 console 对象向 JavaScript 控制台中写入消息,这个对象具有下列方法。
error(message):将错误消息记录到控制台
info(message):将信息性消息记录到控制台
log(message):将一般消息记录到控制台
warn(message):将警告消息记录到控制台
function sum(num1, num2){
console.log("Entering sum(), arguments are " + num1 + "," + num2);
console.log("Before calculation");
var result = num1 + num2;
console.log("After calculation");
console.log("Exiting sum()");
return result;
}
还有一种方案是使用 LiveConnect,也就是在 JavaScript 中运行 Java 代码。 Firefox、 Safari 和 Opera都支持 LiveConnect,因此可以操作 Java 控制台。
function sum(num1, num2){
java.lang.System.out.println("Entering sum(), arguments are " + num1 + "," + num2);
java.lang.System.out.println("Before calculation");
var result = num1 + num2;
java.lang.System.out.println("After calculation");
java.lang.System.out.println("Exiting sum()");
return result;
}
将消息记录到当前页面
function log(message){
var console = document.getElementById("debuginfo");
if (console === null){
console = document.createElement("div");
console.id = "debuginfo";
console.style.background = "#dedede";
console.style.border = "1px solid silver";
console.style.padding = "5px";
console.style.width = "400px";
console.style.position = "absolute";
console.style.right = "0px";
console.style.top = "0px";
document.body.appendChild(console);
}
console.innerHTML += "<p>" + message + "</p>";
}