すべての例外を一緒くたに捕捉するのはバッドノウハウと言われやすいけど、プログラム全体の終了処理には使うので。
問題: 一部の例外が except Exception: をすり抜ける
こんな感じで走らせるスクリプトがあるとして。 最後の except 節で変数に格納するために Exception ですべて拾うようにした。
try:
main()
except KeyboardInterrupt:
pass
except SomeTemporaryError:
print(u'一時的な問題で実行できませんでした。')
except Exception as ex:
notify_error(ex)
print(u'技術的なエラーが発生しました。')
ところがたまに処理できない例外がある。Java の Thread の中から出ているような感じ。
解1: 例外の指定をしない
例外情報は sys.exc_info
で取る。
BaseException 派生、たとえば KeyboardInterrupt や sys.exit() による SystemExit 例外も含まれるようになるのでこれより前で処理しておく必要がある。
except:
ex = sys.exc_info()[1]
notify_error(ex)
これで掴めた例外の祖先を辿っていって判明したのが、
解2: java.lang.Exception も拾う
すり抜けていた例外は Exception ではなく java.lang.Exception
からの派生だった。そういうわけで2つを拾う。
except (Exception, java.lang.Exception) as ex:
notify_error(ex)