WordPress error logging that gives you real context

A client with a high-traffic WooCommerce shop called me up. They were getting hammered with support tickets about an intermittent “invalid coupon code” error at checkout. Some customers saw it, some didn’t. I checked the logs and, of course, they were useless. The standard PHP error log had nothing, and the WooCommerce logs just showed a generic “coupon invalid” line with no context. When you can’t reproduce a bug, you can’t fix it. That is where a sane WordPress error logging strategy stops being a nice-to-have and becomes essential.

My first, gut reaction was to litter the coupon processing functions with error_log(print_r($some_variable, true)). And yes, it dumped a ton of data into the debug.log. But it was a firehose of noise, a big unsearchable text file that didn’t tell me who the user was, what else was in their cart, or what their session data looked like. Classic rookie mistake, and it made the problem worse. An error message without context is just noise.

Beyond basic logging: capturing useful context

The problem isn’t only knowing that an error happened; it’s understanding the state of the application when it broke. This builds on an idea I saw outlined over at carlalexander.ca about designing for error management. You have to think about what a developer needs to do the job. For me it comes down to two things: triaging the error (how bad is it?) and debugging it (what caused it?).

  • For triage: you need a quick summary. What was the error message? How many times has it happened? When did it first and last occur? Is it tied to a specific user role?
  • For debugging: this is where you need the heavy data: the full stack trace, the URL and request method, the full $_POST data, the relevant session data, and in a WooCommerce context, the user’s cart contents.

Instead of dumping raw text, the fix is structured logging. You capture all that context and write it as a clean, predictable JSON object. It’s searchable, parsable, and gives you a full snapshot of the failure.

function custom_contextual_error_log($message, $data = []) {
    $log_entry = [
        'timestamp' => current_time('mysql'),
        'message'   => $message,
        'request'   => [
            'method' => isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'N/A',
            'uri'    => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'N/A',
            'post'   => $_POST,
        ],
        'user'      => [
            'id'   => get_current_user_id(),
            'role' => is_user_logged_in() ? wp_get_current_user()->roles[0] : 'guest',
        ],
        'context'   => $data, // e.g., WC()->cart->get_cart_contents()
    ];

    // Use error_log to write the JSON string to your debug.log
    // In a real-world scenario, you might send this to a dedicated logging service API
    error_log(wp_json_encode($log_entry));
}

// Example usage in WooCommerce
// add_action('woocommerce_coupon_error', 'log_coupon_errors', 10, 2);
// function log_coupon_errors($err_code, $coupon) {
//     custom_contextual_error_log(
//         'WooCommerce Coupon Error: ' . $err_code,
//         [
//             'coupon_code' => $coupon->get_code(),
//             'cart_total'  => WC()->cart->get_cart_total(),
//             'cart_items'  => WC()->cart->get_cart_contents_count(),
//         ]
//     );
// }

So what’s the point?

You don’t need a fancy, expensive logging service to do this well, though one can help. The point is to be deliberate. Stop thinking of logging as printing a message and start thinking of it as serializing the state of your application when things go wrong. Capturing the user, the request, and the application-specific context is what makes debugging efficient and saves you from hours of guesswork.

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

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.