Try catch 的用法

try {
  // do some logic here.
} catch(ex) {
  handleException();
  throw exception;
}
複製代碼

Try Catch 是否越多越好?

不是。應該儘量少。緣由以下:javascript

  • Try catch 會破壞代碼的流暢。打斷邏輯流,不美觀。
  • 系統級通常對 exception 有統一的處理。好比打 log, 錯誤率統計等等。一旦 catch 了 log 又沒有正確拋出的話,就沒有統一的處理。
  • 因此應該儘量的交給底層平臺去處理 exception. 這樣代碼既美觀,error 也能有統一的處理。並且也能讓 app 及時在出錯的地方停下來。

常見的錯誤:java

  • 沒有正確拋出 exception,致使 exception 丟失。(除非你知道本身在幹什麼,下面有膩子)。
try {
// some logic
} catch(ex) {
  console.log(ex);
}
複製代碼
  • 拋出 exception, 可是修改 exception 致使信息丟失。
try {
// some logic
} catch(ex) {
  throw new Error('There is some error occurs!');
}
複製代碼
  • 無心義的 catch
try {
// some logic
} catch(ex) {
  throw ex;
}
複製代碼

何時須要寫 try catch? (假設系統級已經有比較完善的 exception 處理。)

  • 須要忽略出現的 exception。
function isJsonString(str) {
  try {
    JSON.parse(str);
    return true;
  } catch() { 
    return false;
  }
}
複製代碼
  • 須要細化 exception 或者 customize exception. (千萬不要粗化 exception, 如上面 new Error 的例子)
function loadUser(id) {
  try {
    await userModel.get(id);
  } catch(ex) {
    throw new UnauthorizedError(`${}`); // (不太貼切,有沒有更好的膩子)
  }
}
複製代碼

如何正確處理 catch 到的 exception? (上面多數都提到了,再總結一次)

  • 保證 exception 在底層已經處理。(若是沒有,是時候寫點更底層的代碼了)
  • 永遠不要吃掉 exception. 除非你知道本身在作什麼。
  • 儘量不要讓 catch 到的 exception 表述的信息更加模糊,應該是更加精準。除非你知道本身在作什麼。
  • 儘量不要作無心義的 try catch, catch it and just throw it. 除非你知道本身要作什麼。
  • 儘量少寫 try catch.
  • 儘量讓 catch 中的邏輯簡單。以下面的例子,catch 中有複雜的操做,容易 throw exception. (不要把 try catch 當 if else 用)
function loadUser(id, email) {
  try {
    await userModel.getById(id);
  } catch(ex) {
    await userModel.getByEmail(email);
  }
}
複製代碼

何時應該 throw exception?

勇敢的 throw exception, 謹慎的 catch exception. 在方法設計中,應該儘量用 throw 替代狀態返回值。bash

// return true is saved return false if not saved
function saveUser(user) {
  // save user to database
}
複製代碼

True 和 False 是沒法預見全部狀況的,若是 return false, 咱們沒法知道到底出了什麼錯。 Catch exception not saved. No exception saved. 這樣你也能夠只關心正確的邏輯,若是沒有 save 成功自動跳出。app

JS 中有那哪些常見的坑?

最大的問題,JS 是異步的。異步

  • 永遠沒法 catch 到異步的 error.
try {
  setTimeout(()=> {
    throw new Error('Can you catch me?');
  }, 0);
} catch(ex) { 
// catch 不到 
}
複製代碼
function loadUser(id) {
  try {
    userModel.get(id);
  } catch(ex) { 
    // catch 不到
  }
}
複製代碼
try {
  users.forEach(async (user) => {
    await userModel.save(user);
  });
} catch(ex) {
  // catch 不到
}
複製代碼

總結成一句話就是:全部的異步操做都須要 await 之後才能 try catch。除非你知道,本身在作什麼。async

相關文章
相關標籤/搜索