Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ 非同期コードにおけるエラー処理 | Asynchronous Programming
Python構造化プログラミング

非同期コードにおけるエラー処理

メニューを表示するにはスワイプしてください

Pythonでasyncioを使用した非同期コードを扱う際、エラー処理には特別な注意が必要です。例外の伝播方法が同期コードとは異なる場合があるためです。同期的な場合、失敗する可能性のあるコードの周囲にtry-exceptブロックを使用して例外を捕捉します。この構造はコルーチン内でも機能しますが、asyncioによってスケジューリングされたタスクを扱う際には追加の考慮事項があります。

async defコルーチン内で例外が発生し、捕捉されなかった場合、その例外はコルーチンがawaitされる箇所まで伝播します。例外を発生させるコルーチンに対してawaitを使用すると、そのawait箇所で例外が発生し、try-exceptブロックで捕捉できます。しかし、コルーチンをasyncio.create_task()asyncio.ensure_future()でタスクとしてスケジューリングした場合、例外は即座には伝播しません。代わりに、例外はタスクオブジェクト内に保存され、明示的にそのタスクをawaitするか、結果を確認したときにのみ発生します。

つまり、コルーチン内やタスクのawait時に例外を処理しないと、重大なエラーを見逃したり、イベントループによって「未処理の例外」としてログに記録されたりする可能性があります。これを防ぐためには、コルーチン内でtry-exceptを使用して例外を処理するか、すべてのタスクをawaitしてその結果を適切に処理する必要があります。この方法により、非同期プログラムの安定性が保たれ、デバッグも容易になります。

以下は、非同期コルーチン内でtry-exceptブロックを使用して例外を処理する方法を示すPythonコード例です。

import asyncio

async def may_fail(n):
    try:
        if n % 2 == 0:
            raise ValueError(f"Even number error: {n}")
        print(f"Processed: {n}")
    except ValueError as e:
        print(f"Caught exception in coroutine: {e}")

async def main():
    tasks = [asyncio.create_task(may_fail(i)) for i in range(3)]
    await asyncio.gather(*tasks)

asyncio.run(main())

期待される出力:

Caught exception in coroutine: Even number error: 0
Processed: 1
Caught exception in coroutine: Even number error: 2

このコード例では、asyncコルーチンmay_failtry-exceptブロックを使用して、偶数が処理された場合に発生するValueError例外を捕捉します。nが偶数の場合、ValueErrorが発生し、コルーチン内で捕捉されてメッセージが出力されます。mainコルーチンはasyncio.create_task()で3つのタスクをスケジューリングし、asyncio.gather()でそれらをまとめてawaitします。この構成により、コルーチン内で発生した例外が適切に処理され、イベントループに未処理の例外が残らないようになります。

question mark

非同期コルーチンで未処理のエラーを避けるために、例外を適切に処理する方法は?

すべての正しい答えを選択

すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 4.  5

AIに質問する

expand

AIに質問する

ChatGPT

何でも質問するか、提案された質問の1つを試してチャットを始めてください

セクション 4.  5
some-alt