Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Add `send_default_pii` option by default to published config file (#340)
- Update `.gitattributes` to exclude more files from dist release (#341)
- Fixed scope data in queue jobs being lost in some cases (#351)

## 1.7.1

Expand Down
47 changes: 39 additions & 8 deletions src/Sentry/Laravel/EventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Queue\Events\WorkerStopping;
use Illuminate\Queue\QueueManager;
use Illuminate\Routing\Events\RouteMatched;
use Illuminate\Routing\Route;
use Illuminate\Support\Str;
Expand Down Expand Up @@ -98,6 +99,13 @@ class EventHandler
*/
private $recordQueueInfo;

/**
* Indicates if we pushed a scope for the queue.
*
* @var bool
*/
private $pushedQueueScope = false;

/**
* EventHandler constructor.
*
Expand Down Expand Up @@ -135,9 +143,16 @@ public function subscribeAuthEvents()

/**
* Attach all queue event handlers.
*
* @param \Illuminate\Queue\QueueManager $queue
*/
public function subscribeQueueEvents()
public function subscribeQueueEvents(QueueManager $queue)
{
$queue->looping(function () {
$this->cleanupScopeForQueuedJob();
$this->afterQueuedJob();
});

foreach (static::$queueEventHandlerMap as $eventName => $handler) {
$this->events->listen($eventName, [$this, $handler]);
}
Expand Down Expand Up @@ -365,7 +380,7 @@ protected function authenticatedHandler(Authenticated $event)
*/
protected function queueJobProcessingHandler(JobProcessing $event)
{
$this->beforeQueuedJob();
$this->prepareScopeForQueuedJob();

if (!$this->recordQueueInfo) {
return;
Expand Down Expand Up @@ -478,18 +493,34 @@ protected function commandFinishedHandler(CommandFinished $event)
Integration::flushEvents();
}

private function beforeQueuedJob()
private function afterQueuedJob(): void
{
// Flush any and all events that were possibly generated by queue jobs
Integration::flushEvents();
}

private function prepareScopeForQueuedJob(): void
{
// When a job starts, we want to push a new scope
$this->cleanupScopeForQueuedJob();

SentrySdk::getCurrentHub()->pushScope();

$this->pushedQueueScope = true;

// When a job starts, we want to make sure the scope is cleared of breadcrumbs
SentrySdk::getCurrentHub()->configureScope(static function (Scope $scope) {
$scope->clearBreadcrumbs();
});
}

private function afterQueuedJob()
private function cleanupScopeForQueuedJob(): void
{
// Flush any and all events that were possibly generated by queue jobs
Integration::flushEvents();
if (!$this->pushedQueueScope) {
return;
}

// We have added a scope when the job started processing
SentrySdk::getCurrentHub()->popScope();

$this->pushedQueueScope = false;
}
}
4 changes: 3 additions & 1 deletion src/Sentry/Laravel/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ protected function bindEvents(): void

$handler->subscribe();

$handler->subscribeQueueEvents();
if ($this->app->bound('queue')) {
$handler->subscribeQueueEvents($this->app->queue);
}

if (isset($userConfig['send_default_pii']) && $userConfig['send_default_pii'] !== false) {
$handler->subscribeAuthEvents();
Expand Down
17 changes: 12 additions & 5 deletions test/Sentry/SentryLaravelTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

namespace Sentry\Laravel\Tests;

use ReflectionMethod;
use Sentry\Breadcrumb;
use Sentry\State\Scope;
use ReflectionProperty;
use Sentry\State\HubInterface;
use Sentry\Laravel\ServiceProvider;
use Orchestra\Testbench\TestCase as LaravelTestCase;
Expand Down Expand Up @@ -52,17 +55,21 @@ protected function getHubFromContainer(): HubInterface
return $this->app->make('sentry');
}

protected function getCurrentBreadcrumbs(): array
protected function getCurrentScope(): Scope
{
$hub = $this->getHubFromContainer();

$method = new \ReflectionMethod($hub, 'getScope');
$method = new ReflectionMethod($hub, 'getScope');
$method->setAccessible(true);

/** @var \Sentry\State\Scope $scope */
$scope = $method->invoke($hub);
return $method->invoke($hub);
}

protected function getCurrentBreadcrumbs(): array
{
$scope = $this->getCurrentScope();

$property = new \ReflectionProperty($scope, 'breadcrumbs');
$property = new ReflectionProperty($scope, 'breadcrumbs');
$property->setAccessible(true);

return $property->getValue($scope);
Expand Down