rinrin.me

try/catchではなくawait/catchを使おう

async関数はファイルの読み込みや書き込みといった、エラーの可能性を伴うような関数に使われることが多い。この際のエラーハンドリングは通常try/catchパターンで行われる(私もそうしてきた)。

しかし、この方法にはデメリットもある。

などである。

そもそも、tryの中身をデカくして、なんでもcatchしてしまうようなコードを書くのは好ましくない。エラーを握りつぶしてしまう可能性があるからである。

個人的には、try/catchでエラーハンドリングをするよりも、エラーが発生する可能性のある箇所ごとにawait/catchでエラーハンドリングをして、早期リターンなどで対処する、といったコードの方が適切に思う。

await/catchパターンの利点

コード例

// 1/2の確率でエラーを返す関数
const func = async () => {
  if (Math.random() > 0.5) {
    throw new Error("error");
  }
  return "success";
};

// await/catchパターン
const result = await func().catch((err) => err.message);
console.log(result);

// thenでも書けるよ(TypeScriptのPromiseLike型とかで役に立つかも)
const resultWithThen = await func().then(
  (data) => data,
  (err) => err.message,
);

// 早期リターンで関数を正常に終了
(async () => {
  const earlyReturn = await func().catch(() => undefined);
  if (!earlyReturn) {
    return;
  }
  console.log(earlyReturn);
})();