8000 [FrameworkBundle][WebProfilerBundle] Autowiring DataCollector does not work as expected · Issue #41577 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
[FrameworkBundle][WebProfilerBundle] Autowiring DataCollector does not work as expected #41577
Closed
@IonBazan

Description

@IonBazan

Symfony version(s) affected: 5.2+

Description

Problem 1

Injecting any service into a DataCollector extending AbstractDataCollector introduced in #37332 causes a silent exception:

Serialization of 'Closure' is not allowed

This is because __sleep and __wakeup methods are not implemented there to limit serialization to data property only. Since AbstractDataCollector was introduced to reduce boilerplate, it should either extend Symfony\Component\HttpKernel\DataCollector\DataCollector (implementing __sleep and adding cloneVar helper) or implement __sleep on its own. This might be quite tricky for new developers as documentation states that extending AbstractDataCollector is the simplest way to register the collector without any extra configuration.

Problem 2

Customizing DataCollector name using getName and relying on autowire completely causes the template file resolution for the collector to fail. This is because template is registered using service ID (FQCN by default), while collector is added to Profiler using getName() result as profiler ID. This requires user to customize the tag definition in services.yaml:

  App\Infrastructure\DataCollector\DataGridDataCollector:
        tags:
            - name: data_collector
              id: 'data_grid'

which kinda kills the purpose of autoconfiguring functionality.

How to reproduce

Add following class (you may inject any existing service in your app) and use autowire: true:

<?php

namespace App\Infrastructure\DataCollector;

use App\Infrastructure\DataGrid\Debug\DataGridCall;
use App\Infrastructure\DataGrid\Debug\TraceableDataGridHandler;
use Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Throwable;

class DataGridDataCollector extends AbstractDataCollector
{
    public function __construct(private TraceableDataGridHandler $dataGridHandler)
    {
    }

    public function collect(Request $request, Response $response, Throwable $exception = null): void
    {
        $this->data['calls'] = $this->dataGridHandler->getCalls();
    }

    public function reset(): void
    {
        $this->data = [];
        $this->dataGridHandler->clearCalls();
    }

    public function getCalls(): array
    {
        return $this->data['calls'] ?? [];
    }

    public function getName(): string
    {
//        return self::class;
        return 'data_grid';
    }

    public static function getTemplate(): ?string
    {
        return 'data_collector/data_grid.html.twig';
    }
}

Possible Solution

Problem 1

Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector should extend Symfony\Component\HttpKernel\DataCollector\DataCollector (probably breaking change)

Problem 2

🤷🏻‍♂️

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0