0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Flaskで登録したエラーハンドラを無効化する方法

Posted at

はじめに

Flaskのアプリケーションでは エラーハンドラ という機能を用いて例外発生時のレスポンスを制御できます。

@app.errorhandler(errors.MyFlaskAppError)
def handle_my_flask_app_error(e):
    """エラーを補足し、専用のレスポンスを返す。"""

    return jsonify(e.response_body), e.response_status

ドキュメントにもこのことは詳しく記載されていますし、他にも技術系のブログや記事等でもたくさん紹介されているので、Flaskに詳しくない方でも調べればすぐにたどり着ける情報だと思います。
ただ、ハンドラの登録に対してハンドラの無効化に関する情報がなかなか見つからなかったので、メモがてら紹介します。

動作検証環境

  • Python 3.9.1
  • Flask 1.1.2

登録したハンドラを無効化する方法

Flask.error_handler_spec に空の辞書をセットすることで無効化できます!

app.error_handler_spec = {}

想定されるユースケース

わざわざ自分でハンドラを登録しておいて、それを無効化したいってどういうこと?と思われるかもしれませんが、別に変なことをしようとしているわけではありません。
ユースケースとして、単体テスト、特にホワイトボックス的な観点でのテスト(入力に対して開発者が想定している例外が発生していることの確認)を行う際には必要になってくる操作だと思っています。

例えば、実際にpytestを使ってテストする際には、下記のようなコードを書くことでテスト時にのみエラーハンドラを無効化できます。

import pytest

from myflaskapp import create_app
from myflaskapp import errors


@pytest.fixture
def client():
    """テスト用のクライアントを生成する。"""

    # 初期化済みのFlaskアプリケーションを生成します。
    # 記事の本質からズレるので具体的なコードは省略しますが、中でエラーハンドラの登録も行っています。
    app = create_app()

    # テスト時には設定をテストモードに変更します。
    # 詳しくは公式ドキュメントを参照ください。
    # https://flask.palletsprojects.com/en/1.1.x/config/#TESTING
    app.config["TESTING"] = True

    # 例外を補足するために登録した、エラーハンドラを無効化します。
    # これを設定することで、通常であればハンドラで補足される例外を外まで通過させることができます。
    app.error_handler_spec = {}

    # テスト用のクライアントを返します。
    return app.test_client()


def test_request_parameter_is_empty(client):
    """パラメータが空の場合、意図した例外が発生することを確認する。"""

    with pytest.raises(errors.ParameterError):
        client.post("/", json={})
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?