Phoenix custom error doesn't work

I have read phoenix documents and edited my code but it didn’t work for me.

my dev config :

config :trangell_html_site_web, TrangellHtmlSiteWeb.Endpoint,
  http: [port: 9991],
  debug_errors: false,
  code_reloader: true,
  check_origin: false,
  watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin",
                    cd: Path.expand("../assets", __DIR__)]]

my ErrorView :

  def render("404.html", _assigns) do
   "Page not found"
  end

  def render("500.html", _assigns) do
    "Server internal error"
  end

  def template_not_found(template, _assigns) do
    Phoenix.Controller.status_message_from_template(template)
  end

but it shows me :

How can I fix this ?

ref

https://hexdocs.pm/phoenix/errors.html
https://hexdocs.pm/phoenix/views.html#the-errorview

phoenix 1.3 || elixir v1.6.4

That’s a bit weird, just tested on a new app (generated with phx.new task) and it’s working fine… Only thing I changed was the debug_errors option to false as you did. Can you provide an example repo to reproduce the issue?

1 Like

@und0ck3d Thanks, link: https://github.com/shahryarjb/custom_phoenix_error

What is your Elixir version? There is a bug in Elixir before v1.7 where a change of configuration inside the umbrella project was not applying in some cases. If you remove _build at the umbrella root, does the issue still persists?

3 Likes

Hello, my elixir ver is v1.6.4, I removed my _build and I saw this which was fixed. thank you , I’ll update this soon to 1.7

3 Likes

@josevalim
Unfortunately, I have a problem with this part, I want to redirect to html error page but I can’t

defmodule TrangellHtmlSiteWeb.ErrorView do
  use TrangellHtmlSiteWeb, :view

  # If you want to customize a particular status code
  # for a certain format, you may uncomment below.
  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

  def template_not_found(template, _assigns) do
    Phoenix.Controller.status_message_from_template(template)
  end
end

I edited this to

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

but it didn’t work, how can I fix this?

This produces an infinite loop.

1 Like

Then what do I do to fix this? would you mind telling me? Please

1 Like

What is it you actually want? If you want some HTML template rendered, then do so. As far as I remember you simply need to provide the template in the template/error folder and then leave off the render clause.

1 Like

Hmm, Im confused, honestly I need it to show my 404.html.eex instead of text, I have created 2 html .eex before, but I can’t use these.

for example:

<!-- /web/templates/error/404.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">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>404 - Page Not Found</title>
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
  </head>

  <body>
    <h1>404 - Page Not Found</h1>
    <p>This isn't the page you were looking for.</p>
  </body>
</html>

that is my web/templates/error/404.html.eex, but It isn’t shown when I enter broken url. it shows me a text but I want that.


Updated:

now I know, I have to delete all of my codes in My ErrorView except the following line:

def template_not_found(template, _assigns) do
    Phoenix.Controller.status_message_from_template(template)
end

I have 2 questions

q1: when I have 401 or 403 status; What is happens? can I custom them ?
q2: I have a FallbackController please see my code:

defmodule TrangellHtmlSiteWeb.BlogFallbackController do
  use Phoenix.Controller

    def call(conn, {:ok, %HTTPoison.Response{status_code: 404, body: _body}}) do
      conn
      |> put_flash(:info, "متاسفانه صفحه ای که به دنبال آن هستید وجود ندارد.")
      |> render(TrangellHtmlSiteWeb.ErrorView , :"404")
    end
end

I render render(TrangellHtmlSiteWeb.ErrorView , :"404") and it shows me an error in centre of my template, but in the main page if I try like: local.com/404 it just shows me full 404 error page, independently!!

Please see:

pic 1:

pic2:

how can I redirect it to 404full page with the session which I need?

somebody knows what my problem is?
I was forced to use redirect(conn, to: "/404")

path: controllers/blog_fallback_controller.ex

def call(conn, {:ok, %HTTPoison.Response{status_code: 404, body: _body}}) do
      conn
      |> put_flash(:info, "متاسفانه صفحه ای که به دنبال آن هستید وجود ندارد.")
      |> redirect( to: "/404")
 end

and

<!-- /web/templates/error/404.html.eex -->
  <body>
      <%= if Phoenix.Controller.get_flash(@conn, :info) do %>
    <div class="clearfix"> </div>
    <div class="speacer40"></div>
      <div class="alert alert-warning alert-dismissible fade show container rtl-m" role="alert">
        <%= Phoenix.Controller.get_flash(@conn, :info) %>
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
    <% end %>
    <h1>403 - Page Not Found</h1>
    <p>This isn't the page you were looking for.</p>
  </body>

get_flash doesn’t work and I can’t use session, what do I do ?

** (exit) an exception was raised:
    ** (ArgumentError) flash not fetched, call fetch_flash/2
        (phoenix) lib/phoenix/controller.ex:1236: Phoenix.Controller.get_flash/1
        (phoenix) lib/phoenix/controller.ex:1250: Phoenix.Controller.get_flash/2

If you want to do work in a render/2 call but still render a template in the end you can use render_template/2, which you can see in practice here: https://hexdocs.pm/phoenix/1.3.4/Phoenix.Template.html#module-rendering

2 Likes

I added use TrangellHtmlSiteWeb, :controller in MyErrorView like this:

defmodule TrangellHtmlSiteWeb.ErrorView do
  use TrangellHtmlSiteWeb, :view
  use TrangellHtmlSiteWeb, :controller

Do I make a mistake? is this wrong or not? because I am able to get the session in my 404.html.eex now.


Update

it didn’t fix :sweat::frowning_face:, I think this problem won’t be fixed because 404 page is not a router

On Elixir 1.7.4 I got this exact problem in umbrella project and fixed it by deleting _build folder. When I change debug_error flag and I restart the server I don’t see any file recompiled.

1 Like