Skip to content

Commit 48455a5

Browse files
authored
Capture all messenger exceptions (#340)
* Capture exceptions thrown by all messenger handlers * Standardise flush calls on messenger listener * Wrap all test errors in HandlerFailed * Ensure all raised errors are captured * CS space * Capture all errors, not just HandlerFailedException
1 parent 6a4664c commit 48455a5

File tree

2 files changed

+55
-18
lines changed

2 files changed

+55
-18
lines changed

src/EventListener/MessengerListener.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@ public function onWorkerMessageFailed(WorkerMessageFailedEvent $event): void
4141

4242
$error = $event->getThrowable();
4343

44-
if ($error instanceof HandlerFailedException && null !== $error->getPrevious()) {
45-
// Unwrap the messenger exception to get the original error
46-
$error = $error->getPrevious();
44+
if ($error instanceof HandlerFailedException) {
45+
foreach ($error->getNestedExceptions() as $nestedException) {
46+
$this->client->captureException($nestedException);
47+
}
48+
} else {
49+
$this->client->captureException($error);
4750
}
4851

49-
$this->client->captureException($error);
50-
$this->client->flush();
52+
$this->flush();
5153
}
5254

5355
/**
@@ -57,6 +59,11 @@ public function onWorkerMessageHandled(WorkerMessageHandledEvent $event): void
5759
{
5860
// Flush normally happens at shutdown... which only happens in the worker if it is run with a lifecycle limit
5961
// such as --time=X or --limit=Y. Flush immediately in a background worker.
62+
$this->flush();
63+
}
64+
65+
private function flush(): void
66+
{
6067
$this->client->flush();
6168
}
6269
}

test/EventListener/MessengerListenerTest.php

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,37 @@ public function testSoftFailsAreRecorded(): void
2828
self::markTestSkipped('Messenger not supported in this environment.');
2929
}
3030

31+
$message = (object) ['foo' => 'bar'];
32+
$envelope = Envelope::wrap($message);
33+
3134
$error = new \RuntimeException();
35+
$wrappedError = new HandlerFailedException($envelope, [$error]);
3236

3337
$this->client->captureException($error)->shouldBeCalled();
3438
$this->client->flush()->shouldBeCalled();
3539

3640
$listener = new MessengerListener($this->client->reveal(), true);
41+
$event = $this->getMessageFailedEvent($envelope, 'receiver', $wrappedError, true);
42+
43+
$listener->onWorkerMessageFailed($event);
44+
}
45+
46+
public function testNonMessengerErrorsAreRecorded(): void
47+
{
48+
if (! $this->supportsMessenger()) {
49+
self::markTestSkipped('Messenger not supported in this environment.');
50+
}
51+
3752
$message = (object) ['foo' => 'bar'];
3853
$envelope = Envelope::wrap($message);
39-
$event = $this->getMessageFailedEvent($envelope, 'receiver', $error, true);
54+
55+
$error = new \RuntimeException();
56+
57+
$this->client->captureException($error)->shouldBeCalled();
58+
$this->client->flush()->shouldBeCalled();
59+
60+
$listener = new MessengerListener($this->client->reveal(), true);
61+
$event = $this->getMessageFailedEvent($envelope, 'receiver', $error, false);
4062

4163
$listener->onWorkerMessageFailed($event);
4264
}
@@ -47,15 +69,17 @@ public function testHardFailsAreRecorded(): void
4769
self::markTestSkipped('Messenger not supported in this environment.');
4870
}
4971

72+
$message = (object) ['foo' => 'bar'];
73+
$envelope = Envelope::wrap($message);
74+
5075
$error = new \RuntimeException();
76+
$wrappedError = new HandlerFailedException($envelope, [$error]);
5177

5278
$this->client->captureException($error)->shouldBeCalled();
5379
$this->client->flush()->shouldBeCalled();
5480

5581
$listener = new MessengerListener($this->client->reveal(), true);
56-
$message = (object) ['foo' => 'bar'];
57-
$envelope = Envelope::wrap($message);
58-
$event = $this->getMessageFailedEvent($envelope, 'receiver', $error, false);
82+
$event = $this->getMessageFailedEvent($envelope, 'receiver', $wrappedError, false);
5983

6084
$listener->onWorkerMessageFailed($event);
6185
}
@@ -66,15 +90,17 @@ public function testSoftFailsAreNotRecorded(): void
6690
self::markTestSkipped('Messenger not supported in this environment.');
6791
}
6892

93+
$message = (object) ['foo' => 'bar'];
94+
$envelope = Envelope::wrap($message);
95+
6996
$error = new \RuntimeException();
97+
$wrappedError = new HandlerFailedException($envelope, [$error]);
7098

7199
$this->client->captureException($error)->shouldNotBeCalled();
72100
$this->client->flush()->shouldNotBeCalled();
73101

74102
$listener = new MessengerListener($this->client->reveal(), false);
75-
$message = (object) ['foo' => 'bar'];
76-
$envelope = Envelope::wrap($message);
77-
$event = $this->getMessageFailedEvent($envelope, 'receiver', $error, true);
103+
$event = $this->getMessageFailedEvent($envelope, 'receiver', $wrappedError, true);
78104

79105
$listener->onWorkerMessageFailed($event);
80106
}
@@ -85,15 +111,17 @@ public function testHardFailsAreRecordedWithCaptureSoftDisabled(): void
85111
self::markTestSkipped('Messenger not supported in this environment.');
86112
}
87113

114+
$message = (object) ['foo' => 'bar'];
115+
$envelope = Envelope::wrap($message);
116+
88117
$error = new \RuntimeException();
118+
$wrappedError = new HandlerFailedException($envelope, [$error]);
89119

90120
$this->client->captureException($error)->shouldBeCalled();
91121
$this->client->flush()->shouldBeCalled();
92122

93123
$listener = new MessengerListener($this->client->reveal(), false);
94-
$message = (object) ['foo' => 'bar'];
95-
$envelope = Envelope::wrap($message);
96-
$event = $this->getMessageFailedEvent($envelope, 'receiver', $error, false);
124+
$event = $this->getMessageFailedEvent($envelope, 'receiver', $wrappedError, false);
97125

98126
$listener->onWorkerMessageFailed($event);
99127
}
@@ -106,12 +134,14 @@ public function testHandlerFailedExceptionIsUnwrapped(): void
106134

107135
$message = (object) ['foo' => 'bar'];
108136
$envelope = Envelope::wrap($message);
109-
$error = new \RuntimeException();
110-
$wrappedError = new HandlerFailedException($envelope, [$error]);
137+
$error1 = new \RuntimeException();
138+
$error2 = new \RuntimeException();
139+
$wrappedError = new HandlerFailedException($envelope, [$error1, $error2]);
111140

112141
$event = $this->getMessageFailedEvent($envelope, 'receiver', $wrappedError, false);
113142

114-
$this->client->captureException($error)->shouldBeCalled();
143+
$this->client->captureException($error1)->shouldBeCalled();
144+
$this->client->captureException($error2)->shouldBeCalled();
115145
$this->client->flush()->shouldBeCalled();
116146

117147
$listener = new MessengerListener($this->client->reveal());

0 commit comments

Comments
 (0)