程式可能遇到使用者漏填資料、資料型別不正確、網路請求失敗或程式本身寫錯等問題。這些情況不一定都要使用try...catch,可以先按照錯誤是否能預先判斷,以及工作是同步還是非同步來選擇處理方式。
如果是預期中可能發生的輸入問題,可以先用if檢查,再用return結束函式:
function showNickname(nickname) {
if (nickname.trim() === "") {
console.log("請輸入暱稱");
return;
}
console.log(`暱稱:${nickname}`);
}
使用者忘記輸入暱稱是可以預期的情況,直接顯示提示即可,不一定要把它當成程式錯誤。
如果函式收到無法繼續處理的資料,可以使用throw主動產生錯誤並停止目前流程:
function divide(number, divisor) {
if (typeof number !== "number" || typeof divisor !== "number") {
throw new TypeError("兩個值都必須是數字");
}
if (divisor === 0) {
throw new RangeError("除數不能是 0");
}
return number / divisor;
}

throw的作用是回報錯誤,不是處理錯誤。它執行後,函式中剩下的程式不會繼續執行,需要由呼叫函式的地方決定怎麼處理。
呼叫可能產生同步錯誤的函式時,可以使用try...catch:
try {
const result = divide(10, 0);
console.log(result);
} catch (error) {
console.log(error.name); // RangeError
console.log(error.message); // 除數不能是 0
} finally {
console.log("計算結束");
}

try放可能出錯的程式;發生錯誤後會跳到catch;finally則不論成功或失敗都會執行,適合恢復按鈕、關閉載入提示或進行清理。
常見的錯誤類型中,Error表示一般錯誤,TypeError表示資料型別或操作方式不正確,RangeError表示數值超出允許範圍,ReferenceError通常表示使用了不存在的變數,解析錯誤的 JSON 則可能得到SyntaxError。可以透過error.name和error.message查看種類與說明。
Promise失敗時會進入rejected,可以直接在 Promise 鏈後面使用.catch():
const request = Promise.reject(new Error("資料讀取失敗"));
request
.then((data) => console.log(data))
.catch((error) => console.log(error.message))
.finally(() => console.log("請求結束"));
.catch()適合搭配.then()的寫法。若是在async函式中使用await,則可以改用try...catch,讓非同步程式看起來更接近一般由上往下的流程:
async function showRequest() {
try {
const data = await request;
console.log(data);
} catch (error) {
console.log(error.message);
} finally {
console.log("await 處理結束");
}
}

showRequest();
兩種寫法都能處理 Promise 的失敗,差別主要在程式排列方式:使用.then()時接.catch(),使用await時放進try...catch。
console.error()只能把錯誤顯示在主控台,不會阻止錯誤,也不會讓程式恢復正常。錯誤處理的重點是決定失敗後要顯示提示、改用預設值、重新嘗試,還是停止目前操作,最後才使用console.error()留下開發時需要的資訊。