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
14 changes: 14 additions & 0 deletions src/EventType.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ public function requiresEventId(): bool
}
}

/**
* Specifies whether event processors should run for this type of event.
*/
public function requiresEventProcessors(): bool
{
switch ($this) {
case self::event():
case self::transaction():
return true;
default:
return false;
}
}

/**
* Returns false if rate limiting should not be applied.
*/
Expand Down
3 changes: 1 addition & 2 deletions src/Integration/EnvironmentIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use Sentry\Context\RuntimeContext;
use Sentry\Event;
use Sentry\SentrySdk;
use Sentry\State\Scope;
use Sentry\Util\PHPVersion;

/**
Expand All @@ -23,7 +22,7 @@ final class EnvironmentIntegration implements IntegrationInterface
*/
public function setupOnce(): void
{
Scope::addGlobalEventProcessor(static function (Event $event): Event {
SentrySdk::getGlobalScope()->addEventProcessor(static function (Event $event): Event {
$integration = SentrySdk::getClient()->getIntegration(self::class);

if ($integration !== null) {
Expand Down
3 changes: 1 addition & 2 deletions src/Integration/FrameContextifierIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use Sentry\Frame;
use Sentry\SentrySdk;
use Sentry\Stacktrace;
use Sentry\State\Scope;

/**
* This integration reads excerpts of code around the line that originated an
Expand Down Expand Up @@ -40,7 +39,7 @@ public function __construct(?LoggerInterface $logger = null)
*/
public function setupOnce(): void
{
Scope::addGlobalEventProcessor(static function (Event $event): Event {
SentrySdk::getGlobalScope()->addEventProcessor(static function (Event $event): Event {
$client = SentrySdk::getClient();

$maxContextLines = $client->getOptions()->getContextLines();
Expand Down
3 changes: 1 addition & 2 deletions src/Integration/ModulesIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Composer\InstalledVersions;
use Sentry\Event;
use Sentry\SentrySdk;
use Sentry\State\Scope;

/**
* This integration logs with the event details all the versions of the packages
Expand All @@ -25,7 +24,7 @@ final class ModulesIntegration implements IntegrationInterface
*/
public function setupOnce(): void
{
Scope::addGlobalEventProcessor(static function (Event $event): Event {
SentrySdk::getGlobalScope()->addEventProcessor(static function (Event $event): Event {
$integration = SentrySdk::getClient()->getIntegration(self::class);

if ($integration !== null) {
Expand Down
3 changes: 1 addition & 2 deletions src/Integration/RequestIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use Sentry\Options;
use Sentry\OptionsResolver;
use Sentry\SentrySdk;
use Sentry\State\Scope;
use Sentry\UserDataBag;
use Sentry\Util\JSON;

Expand Down Expand Up @@ -103,7 +102,7 @@ public function __construct(?RequestFetcherInterface $requestFetcher = null, arr
*/
public function setupOnce(): void
{
Scope::addGlobalEventProcessor(function (Event $event): Event {
SentrySdk::getGlobalScope()->addEventProcessor(function (Event $event): Event {
$client = SentrySdk::getClient();
$integration = $client->getIntegration(self::class);

Expand Down
3 changes: 1 addition & 2 deletions src/Integration/TransactionIntegration.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Sentry\Event;
use Sentry\EventHint;
use Sentry\SentrySdk;
use Sentry\State\Scope;

/**
* This integration sets the `transaction` attribute of the event to the value
Expand All @@ -23,7 +22,7 @@ final class TransactionIntegration implements IntegrationInterface
*/
public function setupOnce(): void
{
Scope::addGlobalEventProcessor(static function (Event $event, EventHint $hint): Event {
SentrySdk::getGlobalScope()->addEventProcessor(static function (Event $event, EventHint $hint): Event {
$integration = SentrySdk::getClient()->getIntegration(self::class);

if ($integration === null) {
Expand Down
32 changes: 19 additions & 13 deletions src/State/MergedScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,23 +136,29 @@ public function applyToEvent(Event $event, ?EventHint $hint = null, ?Options $op
}
}

foreach (array_merge(parent::$globalEventProcessors, $this->scopeData->getEventProcessors()) as $processor) {
try {
$event = $processor($event, $hint);
} catch (\Throwable $exception) {
if ($options !== null) {
$options->getLoggerOrNullLogger()->error(\sprintf('The event processor failed with exception: "%s".', $exception->getMessage()));
if ($event->getType()->requiresEventProcessors()) {
foreach ($this->scopeData->getEventProcessors() as $processor) {
try {
$event = $processor($event, $hint);
} catch (\Throwable $exception) {
if ($options !== null) {
$options->getLoggerOrNullLogger()->error(\sprintf('The event processor failed with exception: "%s".', $exception->getMessage()));
}

return null;
}

return null;
}
if ($event === null) {
return null;
}

if ($event === null) {
return null;
}
if (!$event instanceof Event) {
if ($options !== null) {
$options->getLoggerOrNullLogger()->debug(\sprintf('The event processor must return null or an instance of the %s class. The event will be discarded.', Event::class));
}

if (!$event instanceof Event) {
throw new \InvalidArgumentException(\sprintf('The event processor must return null or an instance of the %s class', Event::class));
return null;
}
}
}

Expand Down
20 changes: 0 additions & 20 deletions src/State/Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

use Sentry\Breadcrumb;
use Sentry\ClientInterface;
use Sentry\Event;
use Sentry\EventHint;
use Sentry\NoOpClient;
use Sentry\UserDataBag;

Expand All @@ -31,13 +29,6 @@ abstract class Scope
*/
protected $scopeData;

/**
* @var callable[] List of event processors
*
* @phpstan-var array<callable(Event, EventHint): ?Event>
*/
protected static $globalEventProcessors = [];

/**
* @var callable|null
*/
Expand Down Expand Up @@ -75,17 +66,6 @@ public function getBreadcrumbs(): array
return $this->scopeData->getBreadcrumbs();
}

/**
* Adds a new event processor that will be called after {@see MergedScope::applyToEvent}
* finished its work.
*
* @param callable $eventProcessor The event processor
*/
public static function addGlobalEventProcessor(callable $eventProcessor): void
{
self::$globalEventProcessors[] = $eventProcessor;
}

public static function registerExternalPropagationContext(callable $callback): void
{
self::$externalPropagationContextCallback = $callback;
Expand Down
4 changes: 2 additions & 2 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
use Sentry\Frame;
use Sentry\Integration\IntegrationInterface;
use Sentry\Options;
use Sentry\SentrySdk;
use Sentry\Serializer\RepresentationSerializerInterface;
use Sentry\Severity;
use Sentry\Stacktrace;
use Sentry\State\IsolationScope;
use Sentry\State\Scope;
use Sentry\Transport\Result;
use Sentry\Transport\ResultStatus;
use Sentry\Transport\TransportInterface;
Expand Down Expand Up @@ -50,7 +50,7 @@ public function __construct(bool &$integrationCalled)

public function setupOnce(): void
{
Scope::addGlobalEventProcessor(function (): ?Event {
SentrySdk::getGlobalScope()->addEventProcessor(function (): ?Event {
$this->integrationCalled = true;

return null;
Expand Down
69 changes: 69 additions & 0 deletions tests/Integration/IntegrationEventProcessorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace Sentry\Tests\Integration;

use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Sentry\ClientInterface;
use Sentry\Event;
use Sentry\Integration\EnvironmentIntegration;
use Sentry\Integration\FrameContextifierIntegration;
use Sentry\Integration\IntegrationInterface;
use Sentry\Integration\ModulesIntegration;
use Sentry\Integration\RequestIntegration;
use Sentry\Integration\TransactionIntegration;
use Sentry\Options;
use Sentry\SentrySdk;
use Sentry\State\GlobalScope;
use Sentry\State\IsolationScope;

final class IntegrationEventProcessorTest extends TestCase
{
/**
* @dataProvider integrationDataProvider
*/
public function testEventProcessorIsRegisteredOnGlobalScope(IntegrationInterface $integration): void
{
$getIntegrationCalls = 0;

/** @var ClientInterface&MockObject $client */
$client = $this->createMock(ClientInterface::class);
$client->method('getOptions')
->willReturn(new Options());
$client->method('getIntegration')
->willReturnCallback(static function () use (&$getIntegrationCalls): ?IntegrationInterface {
++$getIntegrationCalls;

return null;
});

SentrySdk::init($client);

$integration->setupOnce();

$event = (new GlobalScope())->merge(new IsolationScope())->applyToEvent(Event::createEvent());

$this->assertNotNull($event);
$this->assertSame(0, $getIntegrationCalls);

$event = SentrySdk::getGlobalScope()->merge(new IsolationScope())->applyToEvent(Event::createEvent());

$this->assertNotNull($event);
$this->assertSame(1, $getIntegrationCalls);
}

public static function integrationDataProvider(): \Generator
{
yield [new EnvironmentIntegration()];

yield [new FrameContextifierIntegration()];

yield [new ModulesIntegration()];

yield [new RequestIntegration()];

yield [new TransactionIntegration()];
}
}
9 changes: 0 additions & 9 deletions tests/SentrySdkExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,6 @@ public function executeBeforeTest(string $test): void

StubTransport::$events = [];

$reflectionProperty = new \ReflectionProperty(Scope::class, 'globalEventProcessors');
if (\PHP_VERSION_ID < 80100) {
$reflectionProperty->setAccessible(true);
}
$reflectionProperty->setValue(null, []);
if (\PHP_VERSION_ID < 80100) {
$reflectionProperty->setAccessible(false);
}

$reflectionProperty = new \ReflectionProperty(Scope::class, 'externalPropagationContextCallback');
if (\PHP_VERSION_ID < 80100) {
$reflectionProperty->setAccessible(true);
Expand Down
18 changes: 18 additions & 0 deletions tests/SentrySdkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,24 @@ public function testInitDoesNotResetGlobalScope(): void
$this->assertSame(['baseline' => 'yes'], $event->getTags());
}

public function testInitKeepsGlobalScopeEventProcessors(): void
{
$processorCalled = false;

SentrySdk::getGlobalScope()->addEventProcessor(static function (Event $event) use (&$processorCalled): Event {
$processorCalled = true;

return $event;
});

SentrySdk::init();

$event = SentrySdk::getGlobalScope()->merge(new IsolationScope())->applyToEvent(Event::createEvent());

$this->assertNotNull($event);
$this->assertTrue($processorCalled);
}

public function testStartAndEndContextIsolateScopeData(): void
{
SentrySdk::init();
Expand Down
Loading
Loading