Help us understand the problem. What is going on with this article?

async await に書き換えて、Promiseと 同期による例外の区別でハマった

More than 3 years have passed since last update.

ハマった

元のコード

// async function の中
try {
  load().then(data => {
    console.log(data)
  }).catch(e => {
    // ...
  })
} catch (e) {
  // ... 例外処理
}

わかりやすく簡単にしている。実際にはもっと複雑なコードだった。Promise にすれば
try と catch を一本化して綺麗にできるやん!と思っていた。最初は。

書き換えた

// async function の中
try {
  const data = await load()
  console.log(data)
} catch (e) {
  // ... 例外処理
}

catch が一個減ってリファクタできたーと思っていた。確かに異なる例外処理のブロックが減ってしまっていたが、どうせ何かしらのデッドコードだろと思って消してしまった。

注: 意味的に変わってしまっているが、実際にはすごく複雑なコードで、大きな方のtryは別の例外をキャッチしていると思っていた…

何が起こったか

catch に来てた部分が、Promise の
UnhandledRejectionError になってしまっていた(のにしばらく気づかなかった)。

ここで、状況を述べておくと、 load() はライブラリが提供してた関数で、Promiseを返すことは知っていたが、実装には詳しくなかった。これがハマる理由になった。

挙動をちゃんと追うと、ここの load()同期的な例外 または Promise を返す という実装だった。期待していたのは Promise の resolve or reject だったので、ミスマッチがあったというわけ。

どう直したか

// async function の中
try {
  const loading = load()
  try {
    const data = await loading
    console.log(data)
  } catch (e) {
    // 非同期例外
  }
} catch (e) {
  // 同期例外
}

えーー!!ってコードになってしまった。でもこれが元々期待されてた挙動的に正しい…。

反省

  • async/await の中でも同期例外と非同期例外を区別する
  • 自分がPromiseの関数を実装するときは Promiseのインターフェースに押し込めるようしたいと思った
  • 例外パターンに対するテストは常に書こう

以上、これで2日分ほどハマった現場よりの報告でした。

plaid
CXプラットフォーム「KARTE」の開発・運営、EC特化型メディア「Shopping Tribe」の企画・運営、CX特化型メディア「XD(クロスディー)」の企画・運営
https://plaid.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした