How I built custom error logging in WordPress

A client called last week in a total panic. Their WooCommerce checkout was throwing a 500 error, but only sometimes, and mostly when a customer was about to spend a lot of money. The debug.log file was a 200MB mess of PHP notices from a dozen plugins, so it was useless. They were losing sales and had no idea why. What they needed was a real system for custom error logging in WordPress, not more noise.

The default WordPress debugging tools are fine for a simple blog, but on a complex e-commerce site they fall apart. Turning on WP_DEBUG_LOG on a high-traffic site with a few legacy plugins buries you. You get thousands of lines of warnings, notices, and deprecation messages hiding the one fatal error you actually need to see.

My first thought was to use the native PHP error_log() function to send the important stuff to a separate file. That worked for about five minutes. The problem is you are still just creating another log file. It doesn’t tell you whether an error is a one-off glitch or something that has already happened 5,000 times in the last hour, and it gives you no way to automatically notify the team when a genuinely new issue appears. It was a band-aid on a bullet wound.

A custom error logging fix for WordPress

The only real fix is to stop passively logging and start actively managing errors, which means intercepting them before WordPress does. You do that with PHP’s set_error_handler() function. It lets you route all PHP errors through a custom function you control. Instead of just printing the error, you generate a unique ID for it, a hash based on the error message, the file, and the line number, then store it in a custom database table. This approach was partly inspired by an old post about building an error-tracking app I saw on carlalexander.ca years ago, and the core challenges are still the same.

function custom_error_handler($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) {
        return; // This error is not in error_reporting
    }

    // Create a unique hash for the error type
    $error_hash = md5($message . $file . $line);

    global $wpdb;
    $table_name = $wpdb->prefix . 'app_errors';

    $existing_error = $wpdb->get_row(
        $wpdb->prepare("SELECT * FROM $table_name WHERE error_hash = %s", $error_hash)
    );

    if ($existing_error) {
        // Recurring error: update count and timestamp
        $wpdb->update(
            $table_name,
            ['count' => $existing_error->count + 1, 'last_seen' => current_time('mysql', 1)],
            ['id' => $existing_error->id]
        );
    } else {
        // New error: insert it and send a notification
        $wpdb->insert(
            $table_name,
            [
                'error_hash' => $error_hash,
                'message'    => $message,
                'filename'   => $file,
                'line_number'=> $line,
                'count'      => 1,
                'first_seen' => current_time('mysql', 1),
                'last_seen'  => current_time('mysql', 1),
            ]
        );
        // You would uncomment this in production
        // wp_mail('dev-team@example.com', 'New Production Error', $message);
    }

    // Stop the standard PHP error handler from running.
    return true;
}

set_error_handler('custom_error_handler');

So, what’s the point?

This system does more than log. It triages. You end up with a database table of unique errors, so you can see which ones are new, which happen most often, and you only get one email when a new type of error appears. No more alert fatigue. Instead of a firehose of useless data, you have a short, prioritized list to work from, so you are no longer guessing.

This stuff gets complicated fast. If you are tired of debugging someone else’s mess and you just want your site to work, drop my team a line. We have probably seen it before.

Are you just logging errors, or actually managing them?

author avatar
Ahmad Wael
I'm a WordPress and WooCommerce developer with 15+ years of experience building custom e-commerce solutions and plugins. I specialize in PHP development, following WordPress coding standards to deliver clean, maintainable code. Currently, I'm exploring AI and e-commerce by building multi-agent systems and SaaS products that integrate technologies like Google Gemini API with WordPress platforms, approaching every project with a commitment to performance, security, and exceptional user experience.