From 27a36e24409e52a9e8a65dd631a6a1839aa6cb71 Mon Sep 17 00:00:00 2001 From: Trigrab Date: Wed, 7 May 2025 13:45:43 +0200 Subject: [PATCH 1/2] fix Pre Hook Exception in case _controller is not stringable --- .../Symfony/src/SymfonyInstrumentation.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php b/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php index d74a14263..acc7c66e5 100644 --- a/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php +++ b/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php @@ -47,8 +47,14 @@ public static function register(): void $request = ($params[0] instanceof Request) ? $params[0] : null; $type = $params[1] ?? HttpKernelInterface::MAIN_REQUEST; $method = $request?->getMethod() ?? 'unknown'; + $controller = $request?->attributes?->get('_controller'); + + if (!is_callable($controller, true, $controllerName)) { + $controllerName = 'sub-request'; + } + $name = ($type === HttpKernelInterface::SUB_REQUEST) - ? sprintf('%s %s', $method, $request?->attributes?->get('_controller') ?? 'sub-request') + ? sprintf('%s %s', $method, $controllerName) : $method; /** @psalm-suppress ArgumentTypeCoercion */ $builder = $instrumentation From a8c7f8e5c9da9b6070142a7dc2f40cfe2059e6ce Mon Sep 17 00:00:00 2001 From: Trigrab Date: Thu, 26 Jun 2025 13:54:40 +0200 Subject: [PATCH 2/2] add new test_http_kernel_handle_subrequest_with_various_controller_types integation test --- .../Symfony/src/SymfonyInstrumentation.php | 4 +- .../SymfonyInstrumentationTest.php | 48 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php b/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php index acc7c66e5..4aea37588 100644 --- a/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php +++ b/src/Instrumentation/Symfony/src/SymfonyInstrumentation.php @@ -48,11 +48,11 @@ public static function register(): void $type = $params[1] ?? HttpKernelInterface::MAIN_REQUEST; $method = $request?->getMethod() ?? 'unknown'; $controller = $request?->attributes?->get('_controller'); - + if (!is_callable($controller, true, $controllerName)) { $controllerName = 'sub-request'; } - + $name = ($type === HttpKernelInterface::SUB_REQUEST) ? sprintf('%s %s', $method, $controllerName) : $method; diff --git a/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php b/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php index b9b6401a4..13373b47a 100644 --- a/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php +++ b/src/Instrumentation/Symfony/tests/Integration/SymfonyInstrumentationTest.php @@ -204,6 +204,54 @@ public function test_http_kernel_handle_subrequest(): void $this->assertSame(SpanKind::KIND_INTERNAL, $span->getKind()); } + public function test_http_kernel_handle_subrequest_with_various_controller_types(): void + { + $kernel = $this->getHttpKernel(new EventDispatcher()); + + // String controller + $request = new Request(); + $request->attributes->set('_controller', 'SomeController::index'); + $kernel->handle($request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST); + $this->assertSame('GET SomeController::index', $this->storage[0]->getName()); + $this->storage->exchangeArray([]); + + // Array: [object, method] + $controllerObj = new class() {}; + $request = new Request(); + $request->attributes->set('_controller', [$controllerObj, 'fooAction']); + $kernel->handle($request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST); + $this->assertSame('GET ' . get_class($controllerObj) . '::fooAction', $this->storage[0]->getName()); + $this->storage->exchangeArray([]); + + // Array: [class, method] + $request = new Request(); + $request->attributes->set('_controller', ['SomeClass', 'barAction']); + $kernel->handle($request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST); + $this->assertSame('GET SomeClass::barAction', $this->storage[0]->getName()); + $this->storage->exchangeArray([]); + } + + /** + * @psalm-suppress UnevaluatedCode + */ + public function test_http_kernel_handle_subrequest_with_null_and_object_controller(): void + { + $kernel = $this->getHttpKernel(new EventDispatcher()); + + // Object controller (should fallback to 'sub-request') + $controllerObj2 = new class() {}; + $request = new Request(); + $request->attributes->set('_controller', $controllerObj2); + $kernel->handle($request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST); + $this->assertSame('GET sub-request', $this->storage[0]->getName()); + + // Null/other controller (should fallback to 'sub-request') + $request = new Request(); + $request->attributes->set('_controller', null); + $kernel->handle($request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST); + $this->assertSame('GET sub-request', $this->storage[0]->getName()); + } + private function getHttpKernel(EventDispatcherInterface $eventDispatcher, $controller = null, ?RequestStack $requestStack = null, array $arguments = []): HttpKernel { $controller ??= fn () => new Response('Hello');