Skip to content

Commit c701e16

Browse files
authored
feat: Record handled exceptions (#280)
This change records exceptions even if they are handled by the Kernel. This is handy for apps that have an error handler registered.
1 parent c22df17 commit c701e16

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/Instrumentation/Symfony/src/SymfonyInstrumentation.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,29 @@ public static function register(): void
141141
$span->end();
142142
}
143143
);
144+
145+
hook(
146+
HttpKernel::class,
147+
'handleThrowable',
148+
pre: static function (
149+
HttpKernel $kernel,
150+
array $params,
151+
string $class,
152+
string $function,
153+
?string $filename,
154+
?int $lineno,
155+
): array {
156+
/** @var \Throwable $throwable */
157+
$throwable = $params[0];
158+
159+
Span::getCurrent()
160+
->recordException($throwable, [
161+
TraceAttributes::EXCEPTION_ESCAPED => true,
162+
])
163+
->setStatus(StatusCode::STATUS_ERROR, $throwable->getMessage());
164+
165+
return $params;
166+
},
167+
);
144168
}
145169
}

src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace OpenTelemetry\Tests\Instrumentation\Symfony\tests\Integration;
66

77
use OpenTelemetry\API\Trace\SpanKind;
8+
use OpenTelemetry\API\Trace\StatusCode;
89
use OpenTelemetry\Contrib\Propagation\ServerTiming\ServerTimingPropagator;
910
use OpenTelemetry\Contrib\Propagation\TraceResponse\TraceResponsePropagator;
1011
use OpenTelemetry\SDK\Trace\ImmutableSpan;
@@ -18,6 +19,7 @@
1819
use Symfony\Component\HttpFoundation\StreamedResponse;
1920
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
2021
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
22+
use Symfony\Component\HttpKernel\Exception\HttpException;
2123
use Symfony\Component\HttpKernel\HttpKernel;
2224
use Symfony\Component\HttpKernel\HttpKernelInterface;
2325

@@ -40,6 +42,28 @@ public function test_http_kernel_handle_exception(): void
4042
);
4143
}
4244

45+
public function test_http_kernel_marks_root_as_erroneous(): void
46+
{
47+
$this->expectException(HttpException::class);
48+
$kernel = $this->getHttpKernel(new EventDispatcher(), function () {
49+
throw new HttpException(500, 'foo');
50+
});
51+
$this->assertCount(0, $this->storage);
52+
53+
$response = $kernel->handle(new Request(), HttpKernelInterface::MAIN_REQUEST, true);
54+
55+
$this->assertCount(1, $this->storage);
56+
$this->assertSame(500, $this->storage[0]->getAttributes()->get(TraceAttributes::HTTP_RESPONSE_STATUS_CODE));
57+
58+
$this->assertSame(StatusCode::STATUS_ERROR, $this->storage[0]->getStatus()->getCode());
59+
60+
$this->assertArrayHasKey(
61+
TraceResponsePropagator::TRACERESPONSE,
62+
$response->headers->all(),
63+
'traceresponse header is present if TraceResponsePropagator is present'
64+
);
65+
}
66+
4367
public function test_http_kernel_handle_attributes(): void
4468
{
4569
$kernel = $this->getHttpKernel(new EventDispatcher());

0 commit comments

Comments
 (0)