---
title: All Catch Blocks Must Log Root Cause
impact: HIGH
impactDescription: enables debugging and incident response
tags: error-handling, logging, debugging, observability, quality, php
---

## All Catch Blocks Must Log Root Cause

Silent failures make debugging impossible. Without proper logging of the root cause and relevant context, you cannot trace issues in production or understand why a process failed.

**Incorrect (silent or minimal logging):**

```php
try {
    $this->paymentService->process($order);
} catch (\Exception $e) {
    // Empty catch - silent failure!
}

try {
    $this->userRepository->save($user);
} catch (\Exception $e) {
    return false; // No logging, no context provided for the failure
}
```

**Correct (comprehensive error logging):**

```php
try {
    $this->paymentService->process($order);
} catch (\Throwable $error) {
    // Use a logger (e.g., Monolog, Laravel Log)
    Log::error('Payment processing failed', [
        'order_id' => $order->id,
        'user_id' => $order->user_id,
        'amount' => $order->amount,
        'message' => $error->getMessage(),
        'file' => $error->getFile(),
        'line' => $error->getLine(),
        'trace' => $error->getTraceAsString()
    ]);
    
    // Rethrow or wrap in a custom exception with the original as the cause
    throw new PaymentFailedException('Payment could not be processed', 0, $error);
}
```

**Log context should include:**
- Error message and stack trace (`$e->getMessage()`, `$e->getTraceAsString()`).
- File and line number where the error occurred.
- Relevant entity IDs (order, user, etc.).
- Request/correlation ID (if available).
- Input data that caused the error (careful with sensitive data).

**Tools:** PHPStan, Psalm, SonarQube, PR review
