2

I'm trying to create a fallback for my error_page. Basically, the logic should be something like the following:

  1. load foobar.html
  2. does not exist on remote server -> load 404.html from remote server to show 404 page
  3. does not exist on remote server -> load 404.html on local filesystem

Loading both localhost/404.html and localhost/global404.html works, but when I break localhost/404.html (by removing the file from the http server) it does not show the global404.html page as I'd expect.

server {
    listen 80;
    server_name example.com www.example.com;
    proxy_intercept_errors on;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        error_page 404 /404.html;
    }

    location /404.html {
        proxy_pass http://localhost:3000/404.html;
        error_page 404 /global404.html;
    }

    location /global404.html {
        root /usr/share/nginx/html;
    }
}

The above works fine when I hit http://localhost/404.html (when the 404.html file is on the remote server it shows that, when I delete the file it loads the global404.html file).

However, when I type a non-existent page I just get the default nginx 404 page.

Ola Ström
  • 177
  • 1
  • 1
  • 6
Prisoner
  • 316
  • 1
  • 16
  • 1
    I don't have an authoritative answer, but it seems to me that `error_page` does not cascade. So while Nginx is processing an `error_page` it will not allow another `error_page` to trigger. As both of the errors are triggered remotely, I can't see any viable solution. – Richard Smith May 17 '20 at 10:03
  • that was my assumption. I wonder if there's any other approach I can take with this. I thought `try_files` might be useful but it seems it'll only serve static files and there is no way to get it to proxy. – Prisoner May 17 '20 at 11:37
  • actually @RichardSmith - thanks to your comment i found the answer! Will reply and close it. – Prisoner May 17 '20 at 11:40

1 Answers1

1

Thanks to the wording of a comment left on the question, I managed to find the recursive_error_pages option which allows cascading/recursive error_pages. I feel stupid for missing it in the documentation.

But, simply doing

server {
    listen      80;
    server_name example.com www.example.com;
    proxy_intercept_errors on;
    recursive_error_pages on;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        error_page 404 /404.html;
    }

    location /404.html {
        proxy_pass http://localhost:3000/404.html;
        error_page 404 /global404.html;
    }

    location /global404.html {
        root /usr/share/nginx/html;
    }
}

worked a charm. I love nginx.

Prisoner
  • 316
  • 1
  • 16