Fatal Errors vs Errors vs Warnings
debt(d5/e3/b5/t7)
Closest to 'specialist tool catches' (d5). PHPStan can detect some error suppression patterns and missing error handlers, but the core issue—silent fatal errors in production due to display_errors=Off without logging—often requires runtime testing or production monitoring to catch. Not a simple linter check, but specialist tools can find some patterns.
Closest to 'simple parameterised fix' (e3). The quick_fix shows setting error_reporting(E_ALL) and using set_error_handler() to convert warnings/notices to exceptions. This is a straightforward configuration change plus adding a global error handler—not a one-liner but contained to a few files (bootstrap/config). Doesn't require cross-cutting refactors.
Closest to 'persistent productivity tax' (b5). Error handling strategy applies across all contexts (web, cli, queue-worker per applies_to) and affects every PHP file's behavior. Once you've established an error-silencing pattern or inconsistent error handling, it becomes a persistent drag—debugging becomes harder, monitoring becomes unreliable, and every developer must understand the current error handling setup.
Closest to 'serious trap' (t7). The misconception explicitly states developers believe fatal errors can be caught with try/catch, when in PHP 5 they cannot, and even in PHP 7+ true E_ERROR still terminates. This contradicts how exception handling works in most other languages where all errors are catchable. The Error/Exception distinction in PHP 7+ adds another layer of confusion for developers coming from other ecosystems.
Also Known As
TL;DR
Explanation
PHP's error system has multiple levels controlled by error_reporting(). Fatal errors (E_ERROR) stop execution immediately — you cannot catch them with try/catch, only with register_shutdown_function(). Parse errors (E_PARSE) prevent the file loading at all. Warnings (E_WARNING) continue execution but signal something wrong. Notices (E_NOTICE) are advisory — undefined variables, deprecated usages. PHP 7 replaced many engine-level fatals with catchable Error exceptions.
Common Misconception
Why It Matters
Common Mistakes
- Suppressing all errors with error_reporting(0) hiding real bugs
- Not distinguishing Error exceptions (catchable) from true fatals (not catchable)
- Logging warnings at same severity as fatals in monitoring
Code Examples
// Fatal errors were uncatchable in PHP 5:
require 'nonexistent.php'; // Fatal — script dies, no catch possible
call_to_undefined_function(); // Fatal
// PHP 7+: most fatals are now catchable Errors:
try {
require 'nonexistent.php';
} catch (\Error $e) {
echo 'Fatal caught: ' . $e->getMessage();
}
// Register shutdown for truly uncatchable fatals:
register_shutdown_function(function() {
$error = error_get_last();
if ($error && $error['type'] === E_ERROR) {
error_log('Fatal: ' . $error['message']);
}
});