Subscribe for only $15 to access all of our content

#13: Custom Error Pages in Phoenix

Elixir 1.4

Phoenix 1.2.1

Source code on GitHub


Here we have a phoenix app, but when someone goes to a page that doesn’t exist our app returns a NoRouteError.

Let’s see what this error would look like in if we had deployed our app and one of our users saw it.

The first thing we’ll need to do is go into our config directory and open the ‘dev.exs’ file.

In order to display error pages, we’ll change debug_errors to false.

config/dev.exs

config :teacher, Teacher.Endpoint,
  http: [port: 4000],
  debug_errors: false,
  …

With this change we’ll need to restart our server.

$ mix phoenix.server

And if we go back to our browser and refresh the page, we see a message is returned: “Page not found”.

In this episode we’ll create custom 404 and 500 pages for the application, so let’s get started.

Now this error message is rendered from the the ErrorView, so let’s open up that file.

We can see when it receives a 404 or a 500 it displays a message.

We’ll update these to instead render a template.

For the 404 let’s render a template we’ll call “404_page.html” and for our 500 we’ll render another template named “500_page.html”.

web/views/error_view.ex

defmodule Teacher.ErrorView do
  use Teacher.Web, :view

  def render("404.html", _assigns) do
    render("404_page.html", %{})
  end

  def render("500.html", _assigns) do
    render("500_page.html", %{})  
  end
  …
end

Now let’s create our two templates.

We’ll create a new directory in our templates directory named “error” and inside it we’ll create the matching templates “404_page.html.eex” and “500_page.html.eex”.

I’ve filled the contents of these off screen, but you we can see they are full HTML documents. This is because our error templates our not rendered through our application’s layout.

Template path: web/templates/error/404_page.html.eex

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Nothing to see here</title>
    <link rel="stylesheet" href="/css/app.css">
  </head>
  <body>
    <div class="container">
      <main role="main">
        <h2>404 - Nothing to see here</h2>
      </main>
    </div> <!-- /container -->
  </body>
</html>

Template path: web/templates/error/500_page.html.eex

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>There was an error</title>
    <link rel="stylesheet" href="/css/app.css">
  </head>
  <body>
    <div class="container">
      <main role="main">
        <h2>500 - There was an error</h2>
      </main>
    </div> <!-- /container -->
  </body>
</html>

And with that let’s go back to our browser and if we trigger an error or go to a page that doesn’t exist, we see our custom error templates are now being rendered, perfect.

More Episodes

#112: Deploying with Gigalixir (Revised)

Gigalixir is a Platform as a Service built for Elixir. In this revised episode we’ll see how easy it is to deploy an application to Gigalixir.

Watch episode

#111: Session Testing with Elixir

Often when testing Phoenix controllers you’ll need to initialize the session with data. In this episode we’ll learn how to do just that using the Plug.Test module.

Watch episode

#110: Job Processing with Oban

Oban is a job processing library that uses Postgres. In this episode we’ll add Oban to an existing Elixir project and use it to move some work to the background.

Watch episode