MrG
MrG

Reputation: 382

custom apache 500 error PHP page

Alright, think I am about to loose my mind here...

Been trying and testing, but cannot seem to get a custom HTTP 500 error page to load. Chrome keeps serving me the default "This page isn't working, HTTP error 500" error page.

The steps I have taken:

Accesslog

:1 - - [10/Aug/2018:20:51:39 +0200] "GET / HTTP/1.1" 500 -

Errorlog

[Fri Aug 10 20:51:39.156104 2018] [php7:error] [pid 11608] [client ::1:65263] PHP Fatal error: Uncaught Error: Class 'tests' not found in /private/var/www/development/public_html/index.php:7\nStack trace:\n#0 {main}\n thrown in /private/var/www/development/public_html/index.php on line 7

.htaccess lines

ErrorDocument 400 /404.php
ErrorDocument 403 /403.php
ErrorDocument 404 /404.php
ErrorDocument 405 /405.php
ErrorDocument 408 /408.php
ErrorDocument 500 /500.php
ErrorDocument 502 /502.php
ErrorDocument 504 /504.php

Apache 2.4+ PHP 7+

I am not seeing the issue here, especially since the 404 version above is working flawlessly. 500.php contains just echo '500';

Am I missing some Apache settings here? is it because it is local...

Upvotes: 6

Views: 7296

Answers (1)

TheGentleman
TheGentleman

Reputation: 2362

Your comment is essentially correct. Many 500 errors do will not reach apache in a way that .htaccess will be able to redirect to an error document.

There are 2 ways that you can put out custom templates for 5xx errors. Which one you use will depend on exactly what the error is. If the error is "Catchable" You simply need to wrap your function in a try/catch block. Something like this:

try{
    someUndefinedFunction();
} catch (Throwable $exception) { //Use Throwable to catch both errors and exceptions
    header('HTTP/1.1 500 Internal Server Error'); //Tell the browser this is a 500 error
    echo $e->getMessage();
}

Note that in this example, the 500 error header had to be set manually. This is because since the error is inside a try{} block the server didn't actually error out from the perspective of the browser.

If the 500 error is being caused by something that isn't catchable then you need to register a custom shutdown function. This is less common in php7+ but still may be necessary depending on what you're doing. The way that is done would be to include something like this:

function handle_fatal_error() {
    $error = error_get_last();
    if (is_array($error)) {
        $errorCode = $error['type'] ?? 0;
        $errorMsg = $error['message'] ?? '';
        $file = $error['file'] ?? '';
        $line = $error['line'] ?? null;

        if ($errorCode > 0) {
            handle_error($errorCode, $errorMessage, $file, $line);
        }
    }
}
function handle_error($code, $msg, $file, $line) {
    echo $code . ': '. $msg . 'in ' . $file . 'on line ' . $line;
}
set_error_handler("handle_error");
  register_shutdown_function('handle_fatal_error');

Upvotes: 4

Related Questions