How can I load different error pages depending on conditions? If I’m loading /html/goodpages/test it should try /html/goodpages/test.html unless one of the conditions is true, then it should load the right error page from /html/errorpages. I’ve read about if is evil but it doesn’t explain how to fix it. It’s a very simple case it shouldn’t be so hard.
server {
root /html/goodpages;
if ($condition != 1) {
return 400;
}
if ($condition != 2) {
return 401;
}
if ($condition != 3) {
return 403;
}
try_files $uri.html;
error_page 400 /html/errorpages/error400.html;
error_page 401 /html/errorpages/error401.html;
error_page 402 /html/errorpages/error402.html;
}
I think you are almost there, you would just be missing what is required to make sure you are serving the error pages.
With the return directive, you are indeed defining the error code you want to return (Module ngx_http_rewrite_module), with the error_page, you are defining the URI that should be shown where the error codes happen (Module ngx_http_core_module), but have you made sure that your files in /html/errorpages can be served by NGINX?
From my understanding of the error_page directive’s parameters, it’s not:
Because as explained in the doc, the [uri] parameter is used to perform an “internal redirect”. It’s as if NGINX would make a request to itself to find the content to be returned to the user.
Therefore, for this to work, you’d have to be able to serve the content of your error pages files.
I’d try this conf to edit the one you provided as an example:
I used a different location path and changed root to alias.
Loading /ERRORPAGES/error400.html and /ERRORPAGES/error404.html in the browser return 200 because the /html/errorpages/error400.html and /html/errorpages/error404.html exist.
Loading /DoesntExist returns 404 and shows /html/errorpages/error404.html.
But if the condition is true it shows the default Nginx 400 page not /html/errorpages/error400.html. You can try it with if ($scheme = "http").
So it seems putting your rule in a “location” worked better. Maybe due to the internal redirect nature of the error_page, having the whole server block keeping to trigger a 400 error would not properly allow the error page to work. Could you try and let me know if this works as you’d expect?