{"metadata":{"image":[],"title":"","description":""},"api":{"url":"","auth":"never","settings":"","params":[],"results":{"codes":[]}},"next":{"description":"","pages":[]},"title":"Custom Errors","type":"basic","slug":"custom-errors","excerpt":"","body":"Phoenix provides an `ErrorView`, `web/views/error_view.ex`, to render errors in our applications. The full module name will include the name of our application, as in `HelloPhoenix.ErrorView`.\n\nPhoenix will detect any 400 or 500 status level errors in our application and use the `render/2` function in our `ErrorView` to render an appropriate error template. We get default implementations for 404 and 500 HTML errors, but we can add any clauses to `render/2` that we might need. Any errors which don't match an existing clause of `render/2` will be caught by `template_not_found/2`.\n\nWe can also customize the implementation of any of these functions however we like.\n\nHere's what the `ErrorView` looks like.\n\n```elixir\ndefmodule HelloPhoenix.ErrorView do\n  use HelloPhoenix.Web, :view\n\n  def render(\"404.html\", _assigns) do\n    \"Page not found\"\n  end\n\n  def render(\"500.html\", _assigns) do\n    \"Server internal error\"\n  end\n\n  # In case no render clause matches or no\n  # template is found, let's render it as 500\n  def template_not_found(_template, assigns) do\n    render \"500.html\", assigns\n  end\nend\n```\n\n> NOTE: In the development environment, this behavior will be overridden. Instead, we will get a really great debugging page. In order to see the `ErrorView` in action, we'll need to configure two options - `debug_errors: false` and `catch_errors: true` in `config/dev.exs`.\n\n```elixir\nconfig :hello_phoenix, HelloPhoenix.Endpoint,\n  http: [port: 4000],\n  debug_errors: false,\n  catch_errors: true,\n  code_reloader: true,\n  cache_static_lookup: false,\n  watchers: [node: [\"node_modules/brunch/bin/brunch\", \"watch\"]]\n```\n\nTo learn more about custom error pages, please see [The Error View](http://www.phoenixframework.org/docs/views#section-the-errorview) section of the View Guide.\n\n#### Custom Errors\n\nElixir provides a macro called `defexception` for defining custom exceptions. Exceptions are represented as structs, and structs need to be defined inside of modules.\n\nIn order to create a custom error, we need to define a new module. Conventionally this will have \"Error\" in the name. Inside of that module, we need to define a new exception with `defexception`.\n\nWe can also define a module within a module to provide a namespace for the inner module.\n\nHere's an example from the [Phoenix.Router](https://github.com/phoenixframework/phoenix/blob/master/lib/phoenix/router.ex) which demonstrates all of these ideas.\n\n```elixir\ndefmodule Phoenix.Router do\n  defmodule NoRouteError do\n    :::at:::moduledoc \"\"\"\n    Exception raised when no route is found.\n    \"\"\"\n    defexception plug_status: 404, message: \"no route found\", conn: nil, router: nil\n\n    def exception(opts) do\n      conn   = Keyword.fetch!(opts, :conn)\n      router = Keyword.fetch!(opts, :router)\n      path   = \"/\" <> Enum.join(conn.path_info, \"/\")\n\n      %NoRouteError{message: \"no route found for #{conn.method} #{path} (#{inspect router})\",\n      conn: conn, router: router}\n    end\n  end\n. . .\nend\n```\n\nPlug provides a protocol called `Plug.Exception` specifically for adding a status to exception structs.\n\nIf we wanted to supply a status of 404 for an `Ecto.NoResultsError`, we could do it by defining an implementation for the `Plug.Exception` protocol like this:\n\n```elixir\ndefimpl Plug.Exception, for: Ecto.NoResultsError do\n  def status(_exception), do: 404\nend\n```","updates":[],"order":6,"isReference":false,"hidden":false,"sync_unique":"","link_url":"","link_external":false,"_id":"559218ad1da5250d001e967a","__v":0,"project":"54348ec95b10711400c6c445","user":"5435e00ad7d8700800bbec51","createdAt":"2014-12-03T22:15:51.679Z","githubsync":"","version":{"version":"0.14.0","version_clean":"0.14.0","codename":"","is_stable":false,"is_beta":true,"is_hidden":false,"is_deprecated":false,"categories":["559218ad1da5250d001e9670","559218ad1da5250d001e9671","559218ad1da5250d001e9672","559218ad1da5250d001e9673","559218ad1da5250d001e9674"],"_id":"559218ac1da5250d001e966f","releaseDate":"2015-06-30T04:18:52.132Z","__v":1,"createdAt":"2015-06-30T04:18:52.132Z","forked_from":"5558c642eb56ae2f00f714fc","project":"54348ec95b10711400c6c445"},"category":{"sync":{"isSync":false,"url":""},"pages":["559218ad1da5250d001e9675","559218ad1da5250d001e9676","559218ad1da5250d001e9677","559218ad1da5250d001e9678","559218ad1da5250d001e9679","559218ad1da5250d001e967a","559218ad1da5250d001e967b","559218ad1da5250d001e967c","559218ad1da5250d001e967d","55921ed65068e60d002ba044"],"title":"Bonus Guides","slug":"bonus-guides","order":4,"from_sync":false,"reference":false,"_id":"559218ad1da5250d001e9672","version":"559218ac1da5250d001e966f","__v":2,"createdAt":"2014-12-03T21:36:49.014Z","project":"54348ec95b10711400c6c445"}}
Phoenix provides an `ErrorView`, `web/views/error_view.ex`, to render errors in our applications. The full module name will include the name of our application, as in `HelloPhoenix.ErrorView`. Phoenix will detect any 400 or 500 status level errors in our application and use the `render/2` function in our `ErrorView` to render an appropriate error template. We get default implementations for 404 and 500 HTML errors, but we can add any clauses to `render/2` that we might need. Any errors which don't match an existing clause of `render/2` will be caught by `template_not_found/2`. We can also customize the implementation of any of these functions however we like. Here's what the `ErrorView` looks like. ```elixir defmodule HelloPhoenix.ErrorView do use HelloPhoenix.Web, :view def render("404.html", _assigns) do "Page not found" end def render("500.html", _assigns) do "Server internal error" end # In case no render clause matches or no # template is found, let's render it as 500 def template_not_found(_template, assigns) do render "500.html", assigns end end ``` > NOTE: In the development environment, this behavior will be overridden. Instead, we will get a really great debugging page. In order to see the `ErrorView` in action, we'll need to configure two options - `debug_errors: false` and `catch_errors: true` in `config/dev.exs`. ```elixir config :hello_phoenix, HelloPhoenix.Endpoint, http: [port: 4000], debug_errors: false, catch_errors: true, code_reloader: true, cache_static_lookup: false, watchers: [node: ["node_modules/brunch/bin/brunch", "watch"]] ``` To learn more about custom error pages, please see [The Error View](http://www.phoenixframework.org/docs/views#section-the-errorview) section of the View Guide. #### Custom Errors Elixir provides a macro called `defexception` for defining custom exceptions. Exceptions are represented as structs, and structs need to be defined inside of modules. In order to create a custom error, we need to define a new module. Conventionally this will have "Error" in the name. Inside of that module, we need to define a new exception with `defexception`. We can also define a module within a module to provide a namespace for the inner module. Here's an example from the [Phoenix.Router](https://github.com/phoenixframework/phoenix/blob/master/lib/phoenix/router.ex) which demonstrates all of these ideas. ```elixir 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 ``` Plug provides a protocol called `Plug.Exception` specifically for adding a status to exception structs. If we wanted to supply a status of 404 for an `Ecto.NoResultsError`, we could do it by defining an implementation for the `Plug.Exception` protocol like this: ```elixir defimpl Plug.Exception, for: Ecto.NoResultsError do def status(_exception), do: 404 end ```