技術メモ

プログラミングとか電子工作とか

Phoenix入門 (第15章 Custom Errors)

f:id:ysmn_deus:20190219130922p:plain

どうも、靖宗です。
とりあえず主な項目はコレで最後です。
残るはテストの話とデプロイの話が残っていますが、残ってる話の方が重要そうな気がしますね。

今回はたぶん短めです。
PhoenixというかElixirの例外処理のお話に近いかも。

Custom Errors

Viewsの項目でErrorViewに関しては一回やりました。
基本的に400とか500のエラーはテンプレート(404.html.eexとか)を用意しておけばPhoenixのコントローラがよしなにしてくれます。
ビューのエラーはこのErrorViewで受けるとして、内部処理のエラーはPhoenixでは例外処理などが少々利用されているようです。

Custom Errors

Elixirの標準機能として、例外を定義するためのdefexceptionを利用してエラー処理を行っています。
エラーを実装したいモジュール内部にモジュールを更に定義し、内部でdefexceptionを定義するように実装するそうです。
router.exが利用しているPhoenix.Routerの内部実装が例としてドキュメントに記載されています。

defmodule Phoenix.Router do
  defmodule NoRouteError do
    @moduledoc """
    Exception raised when no route is found.
    """
    defexception plug_status: 404, message: "no route found", conn: nil, router: nil

    def exception(opts) do
      conn   = Keyword.fetch!(opts, :conn)
      router = Keyword.fetch!(opts, :router)
      path   = "/" <> Enum.join(conn.path_info, "/")

      %NoRouteError{message: "no route found for #{conn.method} #{path} (#{inspect router})",
      conn: conn, router: router}
    end
  end
...
end

Elixirの例外処理の記事では取り扱ってなかったのですが、defexceptionを宣言したモジュール内でdef exceptionとして関数を実装すると、エラー処理の関数になるようです。
(詳細はElixirのExceptionのビヘイビアを確認)

Plugを実装する際にはPlug.Exceptionというプロトコルがあるようなのでそちらを利用するのが良いかと思います。
例なども示されてますが、特殊ケースな気がするので、また利用機会があった際に追記したいと思います。

今回は短めですがこんなもんで。