Table of Contents
Pass Dynamic Values as Exception Context, Not in the Message
When throwing exceptions, avoid including dynamic values (like database IDs, user IDs, or timestamps) directly in the exception message. Instead, pass them as context data. This allows error monitoring tools like Sentry to properly group similar errors together instead of treating each unique ID as a separate issue.
Why It Matters
Error monitoring tools use the exception message as the primary grouping key. If your message includes dynamic values, every occurrence creates a new issue, making it impossible to see patterns and track frequency.
Bad Approach
throw new Exception("Order {$orderId} could not be processed");
// Sentry creates separate issues for:
// "Order 123 could not be processed"
// "Order 456 could not be processed"
// "Order 789 could not be processed"
Good Approach
throw new InvalidOrderException(
"Order could not be processed",
['order_id' => $orderId]
);
// All occurrences group under one issue:
// "Order could not be processed" (123 events)
For HTTP Client Exceptions
When working with Guzzle or other HTTP clients, pass context as the second parameter:
try {
return $this->httpClient->request($method, $url, $requestBody);
} catch (RequestException $exception) {
throw ApiClientException::fromGuzzleException(
$exception,
[
'request_data' => json_encode($data),
'request_body' => json_encode($body),
'query_string' => json_encode($query)
]
);
}
Benefits
- Proper error grouping and frequency tracking
- Cleaner error reports
- Easier to identify recurring vs one-off issues
- Context data is still logged and searchable
This applies to any exception in your Laravel application—database exceptions, API errors, validation failures, etc.
Leave a Reply