Errors, Exceptions, Logging, and Debugging
PHP Error Types
| Type | Meaning |
|---|---|
| Parse error | Invalid PHP syntax |
| Fatal error | Execution cannot continue |
| Warning | Problem occurred, execution may continue |
| Notice | Undefined variable/key or similar issue |
| Deprecated | API or behavior should be replaced |
WordPress Debug Constants
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);
Use on development or staging. Do not display errors publicly in production.
Logging
error_log('Reached checkout handler.');
error_log(print_r($settings, true));
Never log passwords, tokens, cookies, full authorization headers, or private user data.
Exceptions
try {
myplugin_risky_operation();
} catch (Throwable $e) {
error_log($e->getMessage());
}
Catch Throwable if you need to catch both Exception and Error.
WP_Error
Many WordPress APIs return WP_Error.
$response = wp_remote_get('https://api.example.com/items');
if (is_wp_error($response)) {
error_log($response->get_error_message());
return [];
}
Create a WP_Error for REST or internal failures.
return new WP_Error(
'myplugin_invalid_request',
__('Invalid request.', 'my-plugin'),
['status' => 400]
);
AJAX Error Response
wp_send_json_error([
'message' => __('Invalid request.', 'my-plugin'),
], 400);
Debugging Checklist
- Reproduce the issue with the smallest action possible.
- Check PHP error logs.
- Confirm the hook or route actually runs.
- Confirm current user and capability.
- Confirm input after unslash and sanitization.
- Check whether the failing API returned
WP_Error. - Disable caching if the symptom is stale output.
- Test with only required plugins if conflict is suspected.
Common Problems
| Symptom | Common Cause |
|---|---|
| White screen | Fatal error |
| Headers already sent | Output before redirect/header |
| Callback not running | Wrong hook or file not loaded |
| REST 404 | Route registered too late or permalinks need flush |
| AJAX returns 0 | Missing action or handler output issue |
| Form saves nothing | Nonce, capability, or name mismatch |
| Infinite redirect | Redirect condition never stops matching |
Production Incident Rules
- Do not edit WordPress core.
- Make one change at a time.
- Preserve logs and backups.
- Disable the suspected plugin or theme safely if needed.
- Roll back code before experimenting with database changes.
- After recovery, write down the cause and prevention.