Table of Contents
The Problem: Generic Exceptions Hide the Real Issue
You’ve probably seen this pattern in your Laravel logs:
throw new \RuntimeException('Operation failed');
When this fires in production, you get a Sentry alert with… basically nothing useful. No context about which operation, what data caused it, or why it failed. Just a vague error message scattered across hundreds of similar failures.
The Solution: Context-Rich Custom Exceptions
Instead of throwing generic exceptions, create specific exception classes that include detailed context. This groups related errors in your monitoring tools and provides actionable debugging information.
class UnsupportedFeatureException extends \RuntimeException
{
public function __construct(string $feature, array $context = [])
{
$message = sprintf(
'Unsupported feature: %s',
$feature
);
parent::__construct($message);
$this->context = array_merge(['feature' => $feature], $context);
}
public function context(): array
{
return $this->context;
}
}
Usage in Your Code
When you need to throw an exception, pass in all the relevant context:
// Instead of this:
if (!$this->supportsFeature($request->feature)) {
throw new \RuntimeException('Feature not supported');
}
// Do this:
if (!$this->supportsFeature($request->feature)) {
throw new UnsupportedFeatureException($request->feature, [
'account_id' => $account->id,
'plan' => $account->plan,
'requested_at' => now()->toDateTimeString(),
]);
}
Reporting to Sentry
Wire up the context in your exception handler so it flows to Sentry:
// app/Exceptions/Handler.php
public function report(Throwable $exception)
{
if (method_exists($exception, 'context')) {
\Sentry\configureScope(function (\Sentry\State\Scope $scope) use ($exception) {
$scope->setContext('exception_details', $exception->context());
});
}
parent::report($exception);
}
Benefits in Production
- Grouped in Sentry: All “UnsupportedFeatureException” errors are grouped together, making it easy to see patterns.
- Actionable context: You see exactly which feature was requested, which account, and what plan they’re on.
- Faster debugging: No more digging through logs trying to reproduce the issue. The context is right there.
- Better alerts: You can set up Sentry alerts based on specific exception types instead of vague error messages.
When to Use This Pattern
Create custom exceptions for:
- Business rule violations (unsupported features, invalid states)
- Integration failures (API timeouts, authentication errors)
- Resource issues (missing files, exceeded quotas)
Keep using generic exceptions for truly unexpected errors where you don’t have meaningful context to add.
Real-World Impact
After implementing context-rich exceptions in our e-commerce platform, we reduced average debugging time from 30+ minutes to under 5 minutes. Instead of searching logs for order IDs and customer details, everything we needed was in the Sentry alert.
Leave a Reply