Interactive debugging with Symfony Console

One of the most important systems we have at RoundingWell is the Evaluation Engine, or “evaluations” as we generally refer to it. This system is responsible for processing customer-specific configured event listeners, which allows us to provide a highl…


This content originally appeared on DEV Community and was authored by Woody Gilk

One of the most important systems we have at RoundingWell is the Evaluation Engine, or "evaluations" as we generally refer to it. This system is responsible for processing customer-specific configured event listeners, which allows us to provide a highly unique user experience for each organization. Needless to say, this system is incredibly important to our application and being able to know exactly what it did, or will do, for a given event is critical.

Today I was working on transitioning one of our customers from some legacy events to newer events and needed to be sure that one of the steps was processing the event correctly. We have a lot of logging around the evaluations, and I knew the information I needed was in the logs. But the problem with having a lot of logging is that, well, there are a lot of logs. Plus, I only needed to run the first part of each trigger to verify that the migration worked.

I thought to myself, "Wouldn't it be clever if we could have an Xdebug-like step debugger for the evaluation engine? I know that Symfony Console has all the functionality I need for this..."

And that was exactly what I did. Because our application is fully dependency injected, I was able to create a new class to wrap the StepFactory, which is responsible for reading the configuration and creating the "steps" that make up the evaluation.

use RoundingWell\Framework\DebugVar;
use RuntimeException;
use Symfony\Component\Console\Style\SymfonyStyle;

readonly class StepFactoryWithConsoleConfirmation implements StepFactory
{
    public function __construct(
        private StepFactory $stepFactory,
        private SymfonyStyle $style,
        private bool $confirmCreatedStep = true,
        private bool $showCreatedStep = true,
        private bool $showStepDefinition = false,
    ) {
    }

    public function create(object $subject, StepDefinition $definition): Step
    {
        if ($this->showStepDefinition) {
            $debug = new DebugVar($definition->parameters);

            $this->style->info(
                message: <<<TEXT
                Next step is $definition->name with parameters:

                $debug
                TEXT,
            );
        }

        $step = $this->stepFactory->create($subject, $definition);

        if ($this->showCreatedStep) {
            $debug = new DebugVar($step);

            $this->style->info(
                message: <<<TEXT
                Step $definition->name created as:

                $debug
                TEXT,
            );
        }

        if ($this->confirmCreatedStep && ! $this->style->confirm(question: "Continue with evaluation?")) {
            throw new RuntimeException(
                message: "Evaluation aborted at step {$definition->name}",
            );
        }

        return $step;
    }
}

And, with a little bit of container manipulation in my console command, we have an interactive evaluation debugger:

use DI\Container;
use RoundingWell\Common\Command\CommandBus;
use RoundingWell\Common\Command\CommandBusComposed;
use RoundingWell\Common\Command\Middleware\LoggingMiddleware;
use RoundingWell\Evaluation\Command\EvaluateEvent;
use RoundingWell\Evaluation\Command\EvaluateEventHandler;
use RoundingWell\Evaluation\Step\StepFactory;
use RoundingWell\Evaluation\Step\StepFactoryWithConsoleConfirmation;
use Symfony\Component\Console\Style\SymfonyStyle;

readonly class EvaluationDebug
{
    public function __construct(
        private Container $container,
    ) {
    }

    public function __invoke(
        SymfonyStyle $symfonyStyle,
        string $eventType,
        string $eventId,
        string|null $evaluationId = null,
    ): void {
        // The command bus MUST ONLY log executed commands.
        $commandBus = new CommandBusComposed(
            $this->container->get(LoggingMiddleware::class),
        );

        // The step factory MUST be wrapped to step through the evaluation.
        $stepFactory = new StepFactoryWithConsoleConfirmation(
            stepFactory: $this->container->get(StepFactory::class),
            style: $symfonyStyle,
        );

        $this->container->set(CommandBus::class, $commandBus);
        $this->container->set(StepFactory::class, $stepFactory);

        $command = new EvaluateEvent(
            eventClass: $eventType,
            eventId: $eventId,
            evaluationId: $evaluationId,
        );

        $this->container->get(EvaluateEventHandler::class)->handle($command);

        $symfonyStyle->success('Evaluation complete');
    }
}

That's it for today!


This content originally appeared on DEV Community and was authored by Woody Gilk


Print Share Comment Cite Upload Translate Updates
APA

Woody Gilk | Sciencx (2024-07-20T12:14:46+00:00) Interactive debugging with Symfony Console. Retrieved from https://www.scien.cx/2024/07/20/interactive-debugging-with-symfony-console/

MLA
" » Interactive debugging with Symfony Console." Woody Gilk | Sciencx - Saturday July 20, 2024, https://www.scien.cx/2024/07/20/interactive-debugging-with-symfony-console/
HARVARD
Woody Gilk | Sciencx Saturday July 20, 2024 » Interactive debugging with Symfony Console., viewed ,<https://www.scien.cx/2024/07/20/interactive-debugging-with-symfony-console/>
VANCOUVER
Woody Gilk | Sciencx - » Interactive debugging with Symfony Console. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/07/20/interactive-debugging-with-symfony-console/
CHICAGO
" » Interactive debugging with Symfony Console." Woody Gilk | Sciencx - Accessed . https://www.scien.cx/2024/07/20/interactive-debugging-with-symfony-console/
IEEE
" » Interactive debugging with Symfony Console." Woody Gilk | Sciencx [Online]. Available: https://www.scien.cx/2024/07/20/interactive-debugging-with-symfony-console/. [Accessed: ]
rf:citation
» Interactive debugging with Symfony Console | Woody Gilk | Sciencx | https://www.scien.cx/2024/07/20/interactive-debugging-with-symfony-console/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.