はじめに
七尾百合子さん、お誕生日 94日目 おめでとうございます! nikkieです。
先日のリリース報告エントリで「HTTPXで例外が送出される箇所の理解が深まりました」と予告した1のを回収します。
目次
まとめ:通信とステータスコードチェックの2箇所
私が理解した内容は、改めてドキュメントを確認すると、QuickstartのExceptionsに書かれていました。
確認不足でやらかしてます... orz
The most important exception classes in HTTPX are
RequestError
andHTTPStatusError
.
try: response = httpx.get("https://www.example.com/") response.raise_for_status() except httpx.RequestError as exc: print(f"An error occurred while requesting {exc.request.url!r}.") except httpx.HTTPStatusError as exc: print(f"Error response {exc.response.status_code} while requesting {exc.request.url!r}.")
httpx.get()
やhttpx.post()
はhttpx.RequestError
を送出するresponse.raise_for_status()
はhttpx.HTTPStatusError
を送出する
tryを狭くしようとしてやらかした
前提としてtry節は最小にしたいです。
- 65:try節は短く書く — 自走プログラマー【抜粋版】
- 「例外処理ではtryブロックは可能な限り小さく保つ」(『Python実践入門』3.4)
結論を繰り返すと、以下の2行は両方try
節に入れる必要があるのですが、
response = httpx.get("https://www.example.com/")
response.raise_for_status()
私は狭いtry
節を作ろうとして誤解していました。
response = httpx.get("https://www.example.com/") try: response.raise_for_status() except httpx.HTTPStatusError: ...
これだとhttpx.get()
で例外が発生し得ますし、try
節の外なのでプログラムが終了してしまいます。
HTTPXの例外のドキュメントより
https://www.python-httpx.org/exceptions/#exception-classes
httpx.RequestError
Base class for all exceptions that may occur when issuing a
.request()
.
httpx.get()
やhttpx.post()
は、内部で.request()
を呼び出していますね。
このHTTPリクエスト(いわばHTTP通信の過程)で問題が起こった場合です。
その1つがTimeoutです2
httpx.HTTPStatusError
May be raised when calling
response.raise_for_status()
HTTP通信に問題はなかったけれど、サーバから4xxや5xxが帰ってきた場合ですね。
httpx.HTTPError
Base class for
RequestError
andHTTPStatusError
.
例外の基底クラスを使って、except
節を1つにまとめられます。
Useful for
try...except
blocks when issuing a request, and then calling.raise_for_status()
.
try: response = httpx.get("https://www.example.com/") response.raise_for_status() except httpx.HTTPError as exc: # RequestError でも HTTPStatusError でも共通の処理
終わりに
llm-devinやllm-openhandsでWeb APIに繰り返しHTTPXでリクエストするときに、書いたようにやらかしたためにRequestError
で処理が落ちていて、今回の内容を学びました。
httpx.request()
ではhttpx.RequestError
が送出されうるresponse.raise_for_status()
ではhttpx.HTTPStatusError
が送出されうる- ゆえに、
try
節には両方を含める必要がある - 基底の
httpx.HTTPError
で両種の例外をまとめて処理できる
ここまで理解すると、例外の名前が送出箇所と対応するのが見えてきますね。
おまけ:HTTPクライアントを知るのは重要です!
JJUG CCC 2025 Springで発表したスライドです
— しろめ (@uskey512) 2025年6月7日
HttpClientはきっと奪うでも与えるでもなくて気が付けばそこにある物といった趣旨の発表をしましたhttps://t.co/7lYFZELdE8