8

I'm trying to create a behaviour such as : if there's a php fatal error, I want the joomla error page to show up, but I also want to receive a mail telling me what the error was.

The idea here is to get rid off the step to check in apache's error log to find out the specific error. I also want my visitor to see the custom error page I've set up.

I've seen a few things that might help me, like "ErrorDocument 500 /myerrorpage" however, I can't see a way to catch the error there.

Is there a way to send a mail containing the error ? The only solution I can see right now is sending a mail like "Hey, someone just landed on the error page, you might want to check out apache's error log to fix it".

PS : If possible I'd like not to use a third party module or plugin, I prefer making my one in terms of security/maintainability

Thanks !

2 Answers 2

5

You'll want to create a custom PHP error handler and have that send you an email.

You can use FILE and FUNCTION and LINE constants to load where the error happened into the email that you alert yourself with.

Take a look at how to do all of that here: https://stackoverflow.com/questions/277224/how-do-i-catch-a-php-fatal-error

4

I've found out that the easiest/faster method to resolve this was to use a script reading apache's logs and send a mail every day with a summary.

FYI : Server's setup has a daily log rotation, run the script through crontab, just before rotation time. (Plus : I'm french, so there are french words in the mail being sent).

Here's the script : (I know it could be improved, but it still does the needed work)

<?php

$start = microtime(true);
$filepath = "PATH/TO/APACHE/LOGS";
$filename = "error.log";
$to = "[email protected]";

$file = file($filepath . $filename);

$warnings = [];
$errors = [];
$notices = [];

foreach($file as $line) {
    $error = strpos($line, "PHP Fatal error");
    if ($error !== false) {
        $exp = explode("PHP Fatal error", $line);
        $exp2 = explode(", referer", $exp[1]);
        $final = "PHP Fatal error" . $exp2[0];
        isset($errors[$final]) ? $errors[$final]+= 1 : $errors[$final]= 1;
    } else {
        $warning = strpos($line, "PHP Warning");
        if ($warning !== false) {
            $exp = explode("PHP Warning", $line);
            $exp2 = explode(", referer", $exp[1]);
            $final = "PHP Warning" . $exp2[0];
            isset($warnings[$final]) ? $warnings[$final]+= 1 : $warnings[$final]= 1;
        } else {
            $notice = strpos($line, "PHP Notice");
            if ($notice !== false) {
                $exp = explode("PHP Notice", $line);
                $exp2 = explode(", referer", $exp[1]);
                $final = "PHP Notice" . $exp2[0];
                isset($notices[$final]) ? $notices[$final]+= 1 : $notices[$final]= 1;
            }
        }
    }
}

$errorNb = countArray($errors);
$warningNb = countArray($warnings);
$noticeNb = countArray($notices);

function countArray($ar) {
    $nb = 0; foreach($ar as $a){ $nb+=$a; } return $nb;
}

$subject = "Rapport apache : Erreurs : " . $errorNb . " - Warnings : " . $warningNb . " - Notices :" .$noticeNb;
$message = "<br>Liste des erreurs (PHP Fatal error) rencontrées :"."<br>";
foreach($errors as $i => $e) {
    $message .= "Rencontré " . $e . " fois : " . $i . "<br>";
}
$message .= "<br>"."<br>Liste des warning (PHP Warning) rencontrées :"."<br>";
foreach($warnings as $i => $e) {
    $message .= "Rencontré " . $e . " fois : " . $i . "<br>";
}
$message .= "<br>"."<br>Liste des erreurs (PHP Notice) rencontrées :"."<br>";
foreach($notices as $i => $e) {
    $message .= "Rencontré " . $e . " fois : " . $i . "<br>";
}

//echo $subject . "<br>" . "<br>";

$message.= "<br><br><br><br>Rapport généré en " . (microtime(true) - $start) . " secondes";

//echo $message;

$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";
3
  • Maybe you want to add lines to delete error.log after the system has sent the email?
    – webchun
    Nov 21, 2016 at 14:33
  • As I said, logs are rotated every day and stored in .gz so that you still have access to them. The server handles that, the script is only for reading + reporting purpose
    – soenguy
    Nov 21, 2016 at 14:44
  • Ah sorry, didn't read that. Anyway, would it be possible to have the script as an installable plugin? We have public JSE repo on github for any installable plugins/modules we're written
    – webchun
    Nov 21, 2016 at 14:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.