當 Javascript 應用程式執行的過程中發生錯誤時, 它會丟出例外狀況(throw exception), Javascript並不會繼續往下執行, 它會尋找有沒有任何 try-catch 程式區塊? 如果沒有就終止, 如果有就執行 catch 內的程式碼.
典型的try-catch 寫法如下
try {
// code
}catch(e) {
// ...
}
在一般的應用程式中想要丟例外錯誤, 則是這樣寫
throw new Error("error message");
如果獲取到例外錯誤, 處理完例外錯誤之後, 又想往外丟例外錯誤, 則可以按照下面示範寫
try {
...
}catch(e) {
//
throw e;
}
Error 是Javascript 內建的錯誤物件. Javascript 提供了以下數個錯誤種類
Error 物件包含了兩個屬性name 和 message
var error = new Error("error message");
console.log(error.name);
console.log(error.message);
例如
var pi = 3.14;
pi.toFixed(1000);
將會噴出RangeError 例外錯誤
Uncaught RangeError: toFixed() digits argument must be between 0 and 100
at Number.toFixed (<anonymous>)
當應用程式試圖存取一個不存在的變數時
console.log(javascript);
會拋出 ReferenceError 例外錯誤
Uncaught ReferenceError: javascript is not defined
例如不小心打錯以下程式碼
for(var i=0, i<1, i++)
會拋出下面錯誤
Uncaught SyntaxError: Unexpected token <
var seafood = {};
seafood.sayHello();
會拋出以下錯誤
Uncaught TypeError: seafood.sayHello is not a function
如果想要獲取例外錯誤種類, 在Javascript 可以這樣寫
try {
...
}catch(e) {
if (exception instanceof TypeError) {
...
} else if (exception instanceof ReferenceError) {
...
} else {
...
}
}
在Javascript 想要自訂例外錯誤的話, 標準的寫法要這樣做
function CustomError(message) {
this.name = 'CustomError';
this.message = message;
}
CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError;
假如我們在Typescript 要自訂例外錯誤, 我們必須遵照Javascript 自訂例外錯誤寫法, 我們可以這樣寫
class CustomError extends Error {
constructor(message?: string) {
super(message);
Object.setPrototypeOf(this, new.target.prototype);
this.name = CustomError.name;
}
}
你可以注意到
Object.setPrototypeOf(this, new.target.prototype);
相當於
CustomError.prototype = new Error();
CustomError.prototype.constructor = CustomError;
在Typescript 如果要獲取自訂的例外錯誤, 跟Javascript 獲取方式一模一樣沒有改變, 請按照下面示範寫,
try {
throw new CustomError();
}
catch(e) {
if(e instanceof CustomError) {
// 錯誤處理動作
}
else {
// 一般的 Error 錯誤
}
}
回到剛剛的遊戲服務 playFun 方法中有許多 logError, 我們可以統一規範所有的方法, 只要方法有任何錯誤, 我們一律都丟例外錯誤 -- PlayFunError
先前有示範過如何撰寫自訂例外錯誤, 我們定義一個 PlayFunError 例外錯誤
class PlayFunError extends Error {
constructor(message?: string) {
super(message);
Object.setPrototypeOf(this, new.target.prototype);
this.name = PlayFunError.name;
}
}