Skip to content

Commit 6b70307

Browse files
authored
Messenger: capture_soft_fails:false doesn't work (#353)
* Add regression test * Apply fix by lowering the MessengerListener priority * Add test for direct capturing from the Messenger * Fix prefer-lowest in CI * Skip test properly in prefer-lowest
1 parent 6817cde commit 6b70307

12 files changed

+316
-8
lines changed

phpstan-baseline.neon

+6-1
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ parameters:
226226
path: test/DependencyInjection/SentryExtensionTest.php
227227

228228
-
229-
message: "#^Method Sentry\\\\SentryBundle\\\\Test\\\\End2End\\\\App\\\\Kernel\\:\\:build\\(\\) has no return typehint specified\\.$#"
229+
message: "#^Comparison operation \"\\>\\=\" between 50102 and 40300 is always true\\.$#"
230230
count: 1
231231
path: test/End2End/App/Kernel.php
232232

@@ -240,6 +240,11 @@ parameters:
240240
count: 1
241241
path: test/End2End/End2EndTest.php
242242

243+
-
244+
message: "#^Comparison operation \"\\<\" between 50102 and 40300 is always false\\.$#"
245+
count: 1
246+
path: test/End2End/End2EndTest.php
247+
243248
-
244249
message: "#^Method Sentry\\\\SentryBundle\\\\Test\\\\ErrorTypesParserTest\\:\\:testParse\\(\\) has parameter \\$value with no typehint specified\\.$#"
245250
count: 1

src/DependencyInjection/Configuration.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public function getConfigTreeBuilder(): TreeBuilder
143143
$listenerPriorities->scalarNode('console_error')
144144
->defaultValue(128);
145145
$listenerPriorities->scalarNode('worker_error')
146-
->defaultValue(128);
146+
->defaultValue(99);
147147

148148
// Monolog handler configuration
149149
$monologConfiguration = $rootNode->children()

test/DependencyInjection/ConfigurationTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function testConfigurationDefaults(): void
5151
'console' => 1,
5252
'request_error' => 128,
5353
'console_error' => 128,
54-
'worker_error' => 128,
54+
'worker_error' => 99,
5555
],
5656
'options' => [
5757
'class_serializers' => [],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Sentry\SentryBundle\Test\End2End\App\Controller;
4+
5+
use Sentry\SentryBundle\Test\End2End\App\Messenger\FooMessage;
6+
use Symfony\Component\HttpFoundation\Response;
7+
use Symfony\Component\Messenger\MessageBusInterface;
8+
9+
class MessengerController
10+
{
11+
/** @var MessageBusInterface */
12+
private $messenger;
13+
14+
public function __construct(MessageBusInterface $messenger)
15+
{
16+
$this->messenger = $messenger;
17+
}
18+
19+
public function dispatchMessage(): Response
20+
{
21+
$this->messenger->dispatch(new FooMessage());
22+
23+
return new Response('Success');
24+
}
25+
26+
public function dispatchUnrecoverableMessage(): Response
27+
{
28+
$this->messenger->dispatch(new FooMessage(false));
29+
30+
return new Response('Success');
31+
}
32+
}

test/End2End/App/Kernel.php

+9-5
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,35 @@
66
use Symfony\Component\DependencyInjection\ContainerBuilder;
77
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
88
use Symfony\Component\HttpKernel\Kernel as SymfonyKernel;
9+
use Symfony\Component\Messenger\MessageBusInterface;
910

1011
class Kernel extends SymfonyKernel
1112
{
1213
/**
1314
* @return BundleInterface[]
1415
*/
15-
public function registerBundles()
16+
public function registerBundles(): array
1617
{
17-
$bundles = [
18+
return [
1819
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
1920
new \Symfony\Bundle\MonologBundle\MonologBundle(),
2021
new \Sentry\SentryBundle\SentryBundle(),
2122
];
22-
23-
return $bundles;
2423
}
2524

2625
public function registerContainerConfiguration(LoaderInterface $loader): void
2726
{
2827
$loader->load(__DIR__ . '/config.yml');
28+
29+
if (interface_exists(MessageBusInterface::class) && self::VERSION_ID >= 40300) {
30+
$loader->load(__DIR__ . '/messenger.yml');
31+
}
2932
}
3033

31-
protected function build(ContainerBuilder $container)
34+
protected function build(ContainerBuilder $container): void
3235
{
3336
$container->setParameter('routing_config_dir', __DIR__);
37+
3438
parent::build($container);
3539
}
3640
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Sentry\SentryBundle\Test\End2End\App\Messenger;
4+
5+
class FooMessage
6+
{
7+
/** @var bool */
8+
private $shouldRetry;
9+
10+
public function __construct(bool $shouldRetry = true)
11+
{
12+
$this->shouldRetry = $shouldRetry;
13+
}
14+
15+
public function shouldRetry(): bool
16+
{
17+
return $this->shouldRetry;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Sentry\SentryBundle\Test\End2End\App\Messenger;
4+
5+
use Symfony\Component\Messenger\Exception\UnrecoverableExceptionInterface;
6+
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
7+
8+
class FooMessageHandler implements MessageHandlerInterface
9+
{
10+
public function __invoke(FooMessage $message): void
11+
{
12+
if (! $message->shouldRetry()) {
13+
throw new class() extends \Exception implements UnrecoverableExceptionInterface {
14+
};
15+
}
16+
17+
throw new \Exception('This is an intentional failure while handling a message of class ' . get_class($message));
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace Sentry\SentryBundle\Test\End2End\App\Messenger;
4+
5+
use Symfony\Component\Messenger\Envelope;
6+
use Symfony\Component\Messenger\Transport\TransportInterface;
7+
8+
/**
9+
* @see \Symfony\Component\Messenger\Transport\InMemoryTransport
10+
*/
11+
class StaticInMemoryTransport implements TransportInterface
12+
{
13+
/** @var Envelope[] */
14+
private static $sent = [];
15+
16+
/** @var Envelope[] */
17+
private static $acknowledged = [];
18+
19+
/** @var Envelope[] */
20+
private static $rejected = [];
21+
22+
/** @var Envelope[] */
23+
private static $queue = [];
24+
25+
/**
26+
* {@inheritdoc}
27+
*/
28+
public function get(): iterable
29+
{
30+
return array_values(self::$queue);
31+
}
32+
33+
/**
34+
* {@inheritdoc}
35+
*/
36+
public function ack(Envelope $envelope): void
37+
{
38+
self::$acknowledged[] = $envelope;
39+
$id = spl_object_hash($envelope->getMessage());
40+
unset(self::$queue[$id]);
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
public function reject(Envelope $envelope): void
47+
{
48+
self::$rejected[] = $envelope;
49+
$id = spl_object_hash($envelope->getMessage());
50+
unset(self::$queue[$id]);
51+
}
52+
53+
/**
54+
* {@inheritdoc}
55+
*/
56+
public function send(Envelope $envelope): Envelope
57+
{
58+
self::$sent[] = $envelope;
59+
$id = spl_object_hash($envelope->getMessage());
60+
self::$queue[$id] = $envelope;
61+
62+
return $envelope;
63+
}
64+
65+
public static function reset(): void
66+
{
67+
self::$sent = self::$queue = self::$rejected = self::$acknowledged = [];
68+
}
69+
70+
/**
71+
* @return Envelope[]
72+
*/
73+
public function getAcknowledged(): array
74+
{
75+
return self::$acknowledged;
76+
}
77+
78+
/**
79+
* @return Envelope[]
80+
*/
81+
public function getRejected(): array
82+
{
83+
return self::$rejected;
84+
}
85+
86+
/**
87+
* @return Envelope[]
88+
*/
89+
public function getSent(): array
90+
{
91+
return self::$sent;
92+
}
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Sentry\SentryBundle\Test\End2End\App\Messenger;
4+
5+
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
6+
use Symfony\Component\Messenger\Transport\TransportFactoryInterface;
7+
use Symfony\Component\Messenger\Transport\TransportInterface;
8+
9+
class StaticInMemoryTransportFactory implements TransportFactoryInterface
10+
{
11+
/**
12+
* @param mixed[] $options
13+
*/
14+
public function createTransport(string $dsn, array $options, SerializerInterface $serializer): TransportInterface
15+
{
16+
return new StaticInMemoryTransport();
17+
}
18+
19+
/**
20+
* @param mixed[] $options
21+
*/
22+
public function supports(string $dsn, array $options): bool
23+
{
24+
return 'static://' === $dsn;
25+
}
26+
}

test/End2End/App/messenger.yml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
services:
2+
_defaults:
3+
autoconfigure: true
4+
5+
Sentry\SentryBundle\Test\End2End\App\Messenger\StaticInMemoryTransportFactory:
6+
class: \Sentry\SentryBundle\Test\End2End\App\Messenger\StaticInMemoryTransportFactory
7+
8+
Sentry\SentryBundle\Test\End2End\App\Messenger\FooMessageHandler:
9+
class: \Sentry\SentryBundle\Test\End2End\App\Messenger\FooMessageHandler
10+
11+
Sentry\SentryBundle\Test\End2End\App\Controller\MessengerController:
12+
autowire: true
13+
tags:
14+
- controller.service_arguments
15+
16+
framework:
17+
messenger:
18+
transports:
19+
async:
20+
dsn: 'static://'
21+
retry_strategy:
22+
max_retries: 1
23+
routing:
24+
'*': async
25+
26+
sentry:
27+
messenger:
28+
capture_soft_fails: false

test/End2End/App/routing.yml

+8
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,11 @@ secured200:
1313
subrequest:
1414
path: /subrequest
1515
defaults: { _controller: 'Sentry\SentryBundle\Test\End2End\App\Controller\MainController::subrequest' }
16+
17+
dispatch:
18+
path: /dispatch-message
19+
defaults: { _controller: 'Sentry\SentryBundle\Test\End2End\App\Controller\MessengerController::dispatchMessage' }
20+
21+
dispatch_unrecoverable:
22+
path: /dispatch-unrecoverable-message
23+
defaults: { _controller: 'Sentry\SentryBundle\Test\End2End\App\Controller\MessengerController::dispatchUnrecoverableMessage' }

0 commit comments

Comments
 (0)