How To Catch All Errors & Exceptions In PHP

Welcome to a quick tutorial on how to catch all errors and exceptions in PHP. Need to cast a net and capture all the errors to figure out what went wrong?

We can capture all errors in PHP using the set_exception_handler() function. For example:

  • function elog ($ex) { error_log($ex->getMessage()); }
  • set_exception_handler($elog);

That covers the quick basics, but read on if you need a detailed example.

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

QUICK SLIDES

 

TABLE OF CONTENTS

Download & Notes Catch Errors Useful Bits & Links
The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

 

PHP CATCH ALL ERRORS

All right, let us now get into examples of catching all errors and exceptions in PHP.

 

1) BASIC PHP ERROR HANDLING

1-basic-error.php
<?php
// (A) ERROR REPORTING LEVEL
// E_ALL, E_WARNING, E_STRICT, E_PARSE, E_DEPRECATED, E_NOTICE
error_reporting(E_ALL); // ALL KINDS OF ERROR
// error_reporting(E_ALL & ~E_NOTICE); // ALL EXCEPT NOTICES
// error_reporting(0); // NO ERROR REPORTING
 
// (B) ERROR LOG
ini_set("log_errors", 1); // SAVE ERROR TO LOG FILE
ini_set("error_log", __DIR__ . DIRECTORY_SEPARATOR . "error.log"); // LOG FILE
 
// (C) DISPLAY ERROR MESSAGES?
ini_set("display_errors", 1);
// NOTE: WILL SHOW "GENERIC" 500 ERROR IF TURNED OFF & NO SET_EXCEPTION_HANDLER()
// NOTE: IF ERROR_REPORTING(0), THIS WILL NOT SHOW ANYTHING.
 
// (X) THROW EXCEPTION
throw new Exception("TEST ERROR!");

First, here is a crash course on the default PHP error handling mechanism. Yes, this is important –

  1. We can set the error report level with error_reporting().
    • PHP has a lot of constants on the error levels. Everything from important E_WARNING to boring E_NOTICE. I will leave a link to the full list below.
    • Of course, we can even turn it off entirely… Which is not recommended.
  2. Next, we can set PHP to save errors into a log file. We can set the defaults in php.ini, but tweak the settings during runtime.
  3. This is the confusing part, there is another setting called display_errors.
    • Not to be confused, error_reporting() controls what kinds of errors need to be reported.
    • While display_errors simply control if the errors should be displayed on the screen; We can turn off display_errors, but keep an error log.

Yep, if you just want to save error messages to a file, just enable log_errors. Don’t need to manually capture all errors and write to a file.

 

 

2) DISPLAYING A CUSTOM ERROR SCREEN

2-custom-error.php
<?php
// (A) ERROR HANDLING SETTINGS
error_reporting(E_ALL & ~E_NOTICE); // ERROR REPORTING LEVEL
ini_set("display_errors", 0); // DO NOT SHOW ERROR MESSAGE
ini_set("log_errors", 1); // SAVE ERROR TO LOG FILE
ini_set("error_log", __DIR__ . DIRECTORY_SEPARATOR . "error.log");
 
// (B) CATCH ALL ERRORS
set_exception_handler(function($ex) {
  // (B1) DO YOUR OWN ERROR HANDLING IF YOU WANT
  // print_r($ex);
  // error_log("YOUR EXTRA MESSAGE OR DATA");
 
  // (B2) SHOW CUSTOM ERROR MESSAGE ?>
  <div style="position:fixed; top:0; left:0; z-index:99999;
       width:100vw; height:100vw; padding:10px; background:#fff">
    <h1>HAIYAA, AN ERROR HAS OCCURED.</h1>
    <p>The developers have been shamed and disowned from the family.</p>
  </div>
<?php });
 
// (X) THROW EXCEPTION
throw new Exception("TEST ERROR!");
echo "This will not run";

As in the introduction above, we use the set_exception_handler() function to capture all the errors and exceptions. In what situation should we do this? If you need to do a “graceful crash”.

  • Save some data, so the user doesn’t lose everything. Or maybe even a possible “recovery” option.
  • Show your custom error message.

 

 

3) SAVE ERROR TO DATABASE

3A) ERROR DATABASE TABLE

3a-error.sql
CREATE TABLE `errors` (
  `date` datetime NOT NULL,
  `file` varchar(255) NOT NULL,
  `line` varchar(255) NOT NULL,
  `message` text NOT NULL,
  `trace` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
ALTER TABLE `errors`
  ADD KEY `date` (`date`);

If you want to save the error into the database, here’s a quick dummy table you can work on.

 

3B) ERROR TO DATABASE

3b-db-error.php
<?php
// (A) CONNECT TO DATABASE - CHANGE SETTINGS TO YOUR OWN!
define("DB_HOST", "localhost");
define("DB_NAME", "test");
define("DB_CHARSET", "utf8");
define("DB_USER", "root");
define("DB_PASSWORD", "");
try {
  $pdo = new PDO(
    "mysql:host=". DB_HOST .";charset=". DB_CHARSET .";dbname=". DB_NAME,
    DB_USER, DB_PASSWORD, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
  ]);
} catch (Exception $ex) { exit("Cannot connect to database."); }
 
// (B) ERROR HANDLING SETTINGS
error_reporting(E_ALL & ~E_NOTICE); // ERROR REPORTING LEVEL
ini_set("display_errors", 0); // DO NOT SHOW ERROR MESSAGE
ini_set("log_errors", 0); // DO NOT SAVE TO LOG FILE
 
// (C) ERROR HANDLER
set_exception_handler(function($ex) {
  // (C1) SAVE ERROR TO DATABASE
  global $pdo;
  $stmt = $pdo->prepare(
    "INSERT INTO `errors`
    (`date`, `file`, `line`, `message`, `trace`)
    VALUES (?, ?, ?, ?, ?)");
  $stmt->execute([
    date("Y-m-d H:i:s"), $ex->getFile(), $ex->getLine(),
    $ex->getMessage(), $ex->getTraceAsString()
  ]);
 
  // (C2) THEN SHOW YOUR CUSTOM ERROR MESSAGE
  echo "Mr. Stark, I don't feel so good.";
});
 
// (X) THROW EXCEPTION
throw new Exception("TEST ERROR!");
echo "This will not run";

This should be pretty self-explanatory – We save any errors into the database instead.

 

 

USEFUL BITS & LINKS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

LINKS & REFERENCES

 

INFOGRAPHIC CHEAT SHEET

Catch All Errors In PHP (Click To Enlarge)

 

THE END

Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

2 thoughts on “How To Catch All Errors & Exceptions In PHP”

    1. Sorry if this is rude, but that snippet makes very little sense.

      1) Read the tutorial carefully, it is about using set_exception_handler() to capture all errors and handle them accordingly.
      2) The error message can be obtained from the exception itself – $ex->getMessage(). Also the file $ex->getFile(), line $ex->getLine(), and stack trace $ex->getTraceAsString().
      3) Notice how I deliberately left out the PHP error code $ex->getCode()? That’s how little value it provided for debugging in years of my web development career. If you need it somehow – https://www.php.net/manual/en/errorfunc.constants.php
      4) BAD idea to display the full error message, code, script name, and line number on a live system. Huge security risk.
      5) Just show a simple “an error has occurred” to the user where possible. Or just the error message without file name, line, trace, and error code.
      6) Keep error details internal – In a log file, or automatically send an email on critical stops.
      7) What’s the point of glorifying the error details in a popup box? Are jQuery and Bootstrap really necessary? If you want to show an error on the screen, just do a <?=$ex->getMessage()?>.

      P.S. The error code is not totally useless. It can still be used for “graceful failures” such as shutting down on critical errors – if (CODE == 4096) { SHUT DOWN }.

Leave a Comment

Your email address will not be published. Required fields are marked *