64:例外を握り潰さない

プログラミング迷子: ユーザーに例外を見せるのは絶対避けたい

  • 先輩T:ここの処理で例外をexceptして return None してるけど、そのまま例外起こしたほうがいいね。

  • 後輩W:なんでですか?

  • 先輩T:そもそもここの処理はファイルがあることが前提だから、想定外のことが起こったらそこでエラーになってプログラムは止まってほしい。

  • 後輩W:でもユーザーにエラーが見えちゃうじゃないですか。

  • 先輩T:ファイルがないままプログラムを継続しても、後続の読み込み処理で結局エラーになるから、継続する意味がないんだよ。

  • 後輩W:たしかに継続することに意味がないですね。

  • 先輩T:しかも、下手に例外処理してるから、エラー原因がファイルがないためなのか、あるけど空なのか、tracebackを読んでもわからないんだよ。

  • 後輩W:ほーん。

  • 先輩T:プログラムで想定外のことが起こったら、素直に例外を上げて終了してくれたほうがいい。すべての不測の事態に備えてコードを書くことはできないからね。

これは「例外を発生させるのは悪、なぜならユーザーに見えてしまうからだ」という発想です。 確かに、ユーザーに例外の詳細を見せる必要はないかもしれません。 しかし、例外の仕組みはプログラミング言語に組み込まれている機能です。 隠蔽するのではなく、活用しましょう。

具体的な失敗

以下の例は、認証が必要なWeb APIにアクセスするコードですが、例外の発生を避けたために本当の原因がわかりづらくなっています。

import requests

def make_auth_header():
    try:
        s = get_secret_key()  # シークレットキーをファイルから読み込み
    except:
        return None
    return {'Authorization': s}

def call_remote_api():
    headers = make_auth_header()
    res = requests.get('http://example.com/remote/api', headers=headers)
    res.raise_for_status()  # ファイルがない場合、ここで認証エラーの例外が発生する
    return res.body

cover

(中略)詳細は書籍 自走プログラマー をご参照ください

ベストプラクティス

想定外の例外を心配して握り潰すのはやめましょう。 エラーが起きたとき問題をユーザーから隠すのではなく、簡単に正しい状態に復帰しやすいように適切な情報を提供してくれるシステムこそ「ユーザーにやさしいシステム」と言えます。 想定される例外の処理は実装するべきですが、想定外のエラーを隠蔽してはいけません。

cover

(中略)詳細は書籍 自走プログラマー をご参照ください