|
2 | 2 |
|
3 | 3 | namespace Sentry\Laravel;
|
4 | 4 |
|
5 |
| -use Illuminate\Database\Eloquent\MissingAttributeException; |
6 |
| -use Illuminate\Database\Eloquent\Model; |
7 |
| -use Illuminate\Database\LazyLoadingViolationException; |
8 | 5 | use Illuminate\Foundation\Configuration\Exceptions;
|
9 | 6 | use Illuminate\Routing\Route;
|
10 | 7 | use Sentry\EventHint;
|
11 | 8 | use Sentry\EventId;
|
12 | 9 | use Sentry\ExceptionMechanism;
|
13 |
| -use Sentry\Laravel\Features\Concerns\ResolvesEventOrigin; |
| 10 | +use Sentry\Laravel\Integration\ModelViolations as ModelViolationReports; |
14 | 11 | use Sentry\SentrySdk;
|
15 |
| -use Sentry\Severity; |
16 | 12 | use Sentry\Tracing\TransactionSource;
|
17 | 13 | use Throwable;
|
18 | 14 | use Sentry\Breadcrumb;
|
@@ -244,105 +240,43 @@ public static function captureUnhandledException(Throwable $throwable): ?EventId
|
244 | 240 | /**
|
245 | 241 | * Returns a callback that can be passed to `Model::handleMissingAttributeViolationUsing` to report missing attribute violations to Sentry.
|
246 | 242 | *
|
247 |
| - * @param callable|null $callback Optional callback to be called after the violation is reported to Sentry. |
| 243 | + * @param callable|null $callback Optional callback to be called after the violation is reported to Sentry. |
| 244 | + * @param bool $suppressDuplicateReports Whether to suppress duplicate reports of the same violation. |
| 245 | + * @param bool $reportAfterResponse Whether to delay sending the report to after the response has been sent. |
248 | 246 | *
|
249 | 247 | * @return callable
|
250 | 248 | */
|
251 |
| - public static function missingAttributeViolationReporter(?callable $callback = null): callable |
| 249 | + public static function missingAttributeViolationReporter(?callable $callback = null, bool $suppressDuplicateReports = true, bool $reportAfterResponse = true): callable |
252 | 250 | {
|
253 |
| - return new class($callback) { |
254 |
| - use ResolvesEventOrigin; |
255 |
| - |
256 |
| - /** @var callable|null $callback */ |
257 |
| - private $callback; |
258 |
| - |
259 |
| - public function __construct(?callable $callback) |
260 |
| - { |
261 |
| - $this->callback = $callback; |
262 |
| - } |
263 |
| - |
264 |
| - public function __invoke(Model $model, string $attribute): void |
265 |
| - { |
266 |
| - SentrySdk::getCurrentHub()->withScope(function (Scope $scope) use ($model, $attribute) { |
267 |
| - $scope->setContext('violation', [ |
268 |
| - 'model' => get_class($model), |
269 |
| - 'attribute' => $attribute, |
270 |
| - 'origin' => $this->resolveEventOrigin(), |
271 |
| - 'kind' => 'missing_attribute', |
272 |
| - ]); |
273 |
| - |
274 |
| - SentrySdk::getCurrentHub()->captureEvent( |
275 |
| - tap(Event::createEvent(), static function (Event $event) { |
276 |
| - $event->setLevel(Severity::warning()); |
277 |
| - }), |
278 |
| - EventHint::fromArray([ |
279 |
| - 'exception' => new MissingAttributeException($model, $attribute), |
280 |
| - 'mechanism' => new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, true), |
281 |
| - ]) |
282 |
| - ); |
283 |
| - }); |
284 |
| - |
285 |
| - // Forward the violation to the next handler if there is one |
286 |
| - if ($this->callback !== null) { |
287 |
| - call_user_func($this->callback, $model, $attribute); |
288 |
| - } |
289 |
| - } |
290 |
| - }; |
| 251 | + return new ModelViolationReports\MissingAttributeModelViolationReporter($callback, $suppressDuplicateReports, $reportAfterResponse); |
291 | 252 | }
|
292 | 253 |
|
293 | 254 | /**
|
294 | 255 | * Returns a callback that can be passed to `Model::handleLazyLoadingViolationUsing` to report lazy loading violations to Sentry.
|
295 | 256 | *
|
296 |
| - * @param callable|null $callback Optional callback to be called after the violation is reported to Sentry. |
| 257 | + * @param callable|null $callback Optional callback to be called after the violation is reported to Sentry. |
| 258 | + * @param bool $suppressDuplicateReports Whether to suppress duplicate reports of the same violation. |
| 259 | + * @param bool $reportAfterResponse Whether to delay sending the report to after the response has been sent. |
297 | 260 | *
|
298 | 261 | * @return callable
|
299 | 262 | */
|
300 |
| - public static function lazyLoadingViolationReporter(?callable $callback = null): callable |
| 263 | + public static function lazyLoadingViolationReporter(?callable $callback = null, bool $suppressDuplicateReports = true, bool $reportAfterResponse = true): callable |
301 | 264 | {
|
302 |
| - return new class($callback) { |
303 |
| - use ResolvesEventOrigin; |
304 |
| - |
305 |
| - /** @var callable|null $callback */ |
306 |
| - private $callback; |
307 |
| - |
308 |
| - public function __construct(?callable $callback) |
309 |
| - { |
310 |
| - $this->callback = $callback; |
311 |
| - } |
| 265 | + return new ModelViolationReports\LazyLoadingModelViolationReporter($callback, $suppressDuplicateReports, $reportAfterResponse); |
| 266 | + } |
312 | 267 |
|
313 |
| - public function __invoke(Model $model, string $relation): void |
314 |
| - { |
315 |
| - // Laravel uses these checks itself to not throw an exception if the model doesn't exist or was just created |
316 |
| - // See: https://github.com/laravel/framework/blob/438d02d3a891ab4d73ffea2c223b5d37947b5e93/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L559-L561 |
317 |
| - if (!$model->exists || $model->wasRecentlyCreated) { |
318 |
| - return; |
319 |
| - } |
320 |
| - |
321 |
| - SentrySdk::getCurrentHub()->withScope(function (Scope $scope) use ($model, $relation) { |
322 |
| - $scope->setContext('violation', [ |
323 |
| - 'model' => get_class($model), |
324 |
| - 'relation' => $relation, |
325 |
| - 'origin' => $this->resolveEventOriginAsString(), |
326 |
| - 'kind' => 'lazy_loading', |
327 |
| - ]); |
328 |
| - |
329 |
| - SentrySdk::getCurrentHub()->captureEvent( |
330 |
| - tap(Event::createEvent(), static function (Event $event) { |
331 |
| - $event->setLevel(Severity::warning()); |
332 |
| - }), |
333 |
| - EventHint::fromArray([ |
334 |
| - 'exception' => new LazyLoadingViolationException($model, $relation), |
335 |
| - 'mechanism' => new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, true), |
336 |
| - ]) |
337 |
| - ); |
338 |
| - }); |
339 |
| - |
340 |
| - // Forward the violation to the next handler if there is one |
341 |
| - if ($this->callback !== null) { |
342 |
| - call_user_func($this->callback, $model, $relation); |
343 |
| - } |
344 |
| - } |
345 |
| - }; |
| 268 | + /** |
| 269 | + * Returns a callback that can be passed to `Model::handleDiscardedAttributeViolationUsing` to report discarded attribute violations to Sentry. |
| 270 | + * |
| 271 | + * @param callable|null $callback Optional callback to be called after the violation is reported to Sentry. |
| 272 | + * @param bool $suppressDuplicateReports Whether to suppress duplicate reports of the same violation. |
| 273 | + * @param bool $reportAfterResponse Whether to delay sending the report to after the response has been sent. |
| 274 | + * |
| 275 | + * @return callable |
| 276 | + */ |
| 277 | + public static function discardedAttributeViolationReporter(?callable $callback = null, bool $suppressDuplicateReports = true, bool $reportAfterResponse = true): callable |
| 278 | + { |
| 279 | + return new ModelViolationReports\DiscardedAttributeViolationReporter($callback, $suppressDuplicateReports, $reportAfterResponse); |
346 | 280 | }
|
347 | 281 |
|
348 | 282 | /**
|
|
0 commit comments