From 38718d2307d035bb6b32ad93fdc2f45eaae98108 Mon Sep 17 00:00:00 2001 From: jan-tricks <113358501+jan-tricks@users.noreply.github.com> Date: Sun, 7 Jan 2024 11:28:00 +0100 Subject: [PATCH 1/2] Add reporter for `Model::preventSilentlyDiscardingAttributes()` --- src/Sentry/Laravel/Integration.php | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/Sentry/Laravel/Integration.php b/src/Sentry/Laravel/Integration.php index df319a9f..5f17b64d 100644 --- a/src/Sentry/Laravel/Integration.php +++ b/src/Sentry/Laravel/Integration.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\LazyLoadingViolationException; +use Illuminate\Database\MassAssignmentException; use Illuminate\Routing\Route; use Sentry\EventHint; use Sentry\EventId; @@ -269,6 +270,60 @@ public function __invoke(Model $model, string $relation): void }; } + /** + * Returns a callback that can be passed to `Model::handleDiscardedAttributeViolationUsing` to report discarded attribute violations to Sentry. + * + * @param callable|null $callback Optional callback to be called after the violation is reported to Sentry. + * + * @return callable + */ + public static function discardedAttributeViolationReporter(?callable $callback = null): callable + { + return new class($callback) { + use ResolvesEventOrigin; + + /** @var callable|null $callback */ + private $callback; + + public function __construct(?callable $callback) + { + $this->callback = $callback; + } + + public function __invoke(Model $model, array $attributes): void + { + $attributes = implode(', ', $attributes); + SentrySdk::getCurrentHub()->withScope(function (Scope $scope) use ($model, $attributes) { + $scope->setContext('violation', [ + 'model' => get_class($model), + 'attributes' => $attributes, + 'origin' => $this->resolveEventOrigin(), + 'kind' => 'discarded_attributes', + ]); + + SentrySdk::getCurrentHub()->captureEvent( + tap(Event::createEvent(), static function (Event $event) { + $event->setLevel(Severity::warning()); + }), + EventHint::fromArray([ + 'exception' => new MassAssignmentException(sprintf( + 'Add fillable property [%s] to allow mass assignment on [%s].', + $attributes, + get_class($model) + )), + 'mechanism' => new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, true), + ]) + ); + }); + + // Forward the violation to the next handler if there is one + if ($this->callback !== null) { + call_user_func($this->callback, $model, $attribute); + } + } + }; + } + /** * Try to make an educated guess if the call came from the Laravel `report` helper. * From 492f11476b47d4edb049635898476da05bc26ebd Mon Sep 17 00:00:00 2001 From: jan-tricks Date: Sun, 7 Jan 2024 17:52:16 +0100 Subject: [PATCH 2/2] fix naming of variable in discardedAttributeViolationReporter --- src/Sentry/Laravel/Integration.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Sentry/Laravel/Integration.php b/src/Sentry/Laravel/Integration.php index 5f17b64d..fba35d24 100644 --- a/src/Sentry/Laravel/Integration.php +++ b/src/Sentry/Laravel/Integration.php @@ -292,11 +292,11 @@ public function __construct(?callable $callback) public function __invoke(Model $model, array $attributes): void { - $attributes = implode(', ', $attributes); - SentrySdk::getCurrentHub()->withScope(function (Scope $scope) use ($model, $attributes) { + $attributes_imploded = implode(', ', $attributes); + SentrySdk::getCurrentHub()->withScope(function (Scope $scope) use ($model, $attributes_imploded) { $scope->setContext('violation', [ 'model' => get_class($model), - 'attributes' => $attributes, + 'attributes' => $attributes_imploded, 'origin' => $this->resolveEventOrigin(), 'kind' => 'discarded_attributes', ]); @@ -308,7 +308,7 @@ public function __invoke(Model $model, array $attributes): void EventHint::fromArray([ 'exception' => new MassAssignmentException(sprintf( 'Add fillable property [%s] to allow mass assignment on [%s].', - $attributes, + $attributes_imploded, get_class($model) )), 'mechanism' => new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, true), @@ -318,7 +318,7 @@ public function __invoke(Model $model, array $attributes): void // Forward the violation to the next handler if there is one if ($this->callback !== null) { - call_user_func($this->callback, $model, $attribute); + call_user_func($this->callback, $model, $attributes); } } };