Skip to content

Commit 04d4280

Browse files
authored
ref: Expose the ExceptionMechanism through the event hint (#1416)
1 parent 8a2ae1d commit 04d4280

File tree

5 files changed

+63
-3
lines changed

5 files changed

+63
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
ref: Enable the ModulesIntegration by default (#1415)
6+
ref: Expose the ExceptionMechanism through the event hint (#1416)
67

78
## 3.10.0 (2022-10-19)
89

src/Client.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ private function prepareEvent(Event $event, ?EventHint $hint = null, ?Scope $sco
248248
{
249249
if (null !== $hint) {
250250
if (null !== $hint->exception && empty($event->getExceptions())) {
251-
$this->addThrowableToEvent($event, $hint->exception);
251+
$this->addThrowableToEvent($event, $hint->exception, $hint);
252252
}
253253

254254
if (null !== $hint->stacktrace && null === $event->getStacktrace()) {
@@ -338,8 +338,9 @@ private function addMissingStacktraceToEvent(Event $event): void
338338
*
339339
* @param Event $event The event that will be enriched with the exception
340340
* @param \Throwable $exception The exception that will be processed and added to the event
341+
* @param EventHint $hint Contains additional information about the event
341342
*/
342-
private function addThrowableToEvent(Event $event, \Throwable $exception): void
343+
private function addThrowableToEvent(Event $event, \Throwable $exception, EventHint $hint): void
343344
{
344345
if ($exception instanceof \ErrorException && null === $event->getLevel()) {
345346
$event->setLevel(Severity::fromError($exception->getSeverity()));
@@ -351,7 +352,7 @@ private function addThrowableToEvent(Event $event, \Throwable $exception): void
351352
$exceptions[] = new ExceptionDataBag(
352353
$exception,
353354
$this->stacktraceBuilder->buildFromException($exception),
354-
new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, true)
355+
$hint->mechanism ?? new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, true)
355356
);
356357
} while ($exception = $exception->getPrevious());
357358

src/EventHint.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ final class EventHint
1616
*/
1717
public $exception;
1818

19+
/**
20+
* An object describing the mechanism of the original exception.
21+
*
22+
* @var ExceptionMechanism|null
23+
*/
24+
public $mechanism;
25+
1926
/**
2027
* The stacktrace to set on the event.
2128
*
@@ -43,13 +50,18 @@ public static function fromArray(array $hintData): self
4350
{
4451
$hint = new self();
4552
$exception = $hintData['exception'] ?? null;
53+
$mechanism = $hintData['mechanism'] ?? null;
4654
$stacktrace = $hintData['stacktrace'] ?? null;
4755
$extra = $hintData['extra'] ?? [];
4856

4957
if (null !== $exception && !$exception instanceof \Throwable) {
5058
throw new \InvalidArgumentException(sprintf('The value of the "exception" field must be an instance of a class implementing the "%s" interface. Got: "%s".', \Throwable::class, get_debug_type($exception)));
5159
}
5260

61+
if (null !== $mechanism && !$mechanism instanceof ExceptionMechanism) {
62+
throw new \InvalidArgumentException(sprintf('The value of the "mechanism" field must be an instance of the "%s" class. Got: "%s".', ExceptionMechanism::class, get_debug_type($mechanism)));
63+
}
64+
5365
if (null !== $stacktrace && !$stacktrace instanceof Stacktrace) {
5466
throw new \InvalidArgumentException(sprintf('The value of the "stacktrace" field must be an instance of the "%s" class. Got: "%s".', Stacktrace::class, get_debug_type($stacktrace)));
5567
}
@@ -59,6 +71,7 @@ public static function fromArray(array $hintData): self
5971
}
6072

6173
$hint->exception = $exception;
74+
$hint->mechanism = $mechanism;
6275
$hint->stacktrace = $stacktrace;
6376
$hint->extra = $extra;
6477

tests/ClientTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,42 @@ public function testBuildEventWithException(): void
705705
]));
706706
}
707707

708+
public function testBuildEventWithExceptionAndMechansim(): void
709+
{
710+
$options = new Options();
711+
$exception = new \Exception('testMessage');
712+
713+
/** @var TransportInterface&MockObject $transport */
714+
$transport = $this->createMock(TransportInterface::class);
715+
$transport->expects($this->once())
716+
->method('send')
717+
->with($this->callback(function (Event $event): bool {
718+
$capturedExceptions = $event->getExceptions();
719+
720+
$this->assertCount(1, $capturedExceptions);
721+
$this->assertNotNull($capturedExceptions[0]->getStacktrace());
722+
$this->assertEquals(new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, false), $capturedExceptions[0]->getMechanism());
723+
$this->assertSame(\Exception::class, $capturedExceptions[0]->getType());
724+
$this->assertSame('testMessage', $capturedExceptions[0]->getValue());
725+
726+
return true;
727+
}));
728+
729+
$client = new Client(
730+
$options,
731+
$transport,
732+
'sentry.sdk.identifier',
733+
'1.2.3',
734+
new Serializer($options),
735+
$this->createMock(RepresentationSerializerInterface::class)
736+
);
737+
738+
$client->captureEvent(Event::createEvent(), EventHint::fromArray([
739+
'exception' => $exception,
740+
'mechanism' => new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, false),
741+
]));
742+
}
743+
708744
public function testBuildWithErrorException(): void
709745
{
710746
$options = new Options();

tests/EventHintTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use PHPUnit\Framework\TestCase;
88
use Sentry\EventHint;
9+
use Sentry\ExceptionMechanism;
910
use Sentry\Frame;
1011
use Sentry\Stacktrace;
1112

@@ -14,17 +15,20 @@ final class EventHintTest extends TestCase
1415
public function testCreateFromArray(): void
1516
{
1617
$exception = new \Exception();
18+
$mechanism = new ExceptionMechanism(ExceptionMechanism::TYPE_GENERIC, false);
1719
$stacktrace = new Stacktrace([
1820
new Frame('function_1', 'path/to/file_1', 10),
1921
]);
2022

2123
$hint = EventHint::fromArray([
2224
'exception' => $exception,
25+
'mechanism' => $mechanism,
2326
'stacktrace' => $stacktrace,
2427
'extra' => ['foo' => 'bar'],
2528
]);
2629

2730
$this->assertSame($exception, $hint->exception);
31+
$this->assertSame($mechanism, $hint->mechanism);
2832
$this->assertSame($stacktrace, $hint->stacktrace);
2933
$this->assertSame(['foo' => 'bar'], $hint->extra);
3034
}
@@ -47,6 +51,11 @@ public function createFromArrayWithInvalidValuesDataProvider(): \Generator
4751
'The value of the "exception" field must be an instance of a class implementing the "Throwable" interface. Got: "string".',
4852
];
4953

54+
yield [
55+
['mechanism' => 'foo'],
56+
'The value of the "mechanism" field must be an instance of the "Sentry\\ExceptionMechanism" class. Got: "string".',
57+
];
58+
5059
yield [
5160
['stacktrace' => 'foo'],
5261
'The value of the "stacktrace" field must be an instance of the "Sentry\\Stacktrace" class. Got: "string".',

0 commit comments

Comments
 (0)