Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
LogDeferredCallbackFailure
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
2 / 2
2
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __invoke
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of fast-forward/defer.
7 *
8 * This source file is subject to the license bundled
9 * with this source code in the file LICENSE.
10 *
11 * @copyright Copyright (c) 2026 Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
12 * @license   https://opensource.org/licenses/MIT MIT License
13 *
14 * @see       https://github.com/php-fast-forward/defer
15 * @see       https://github.com/php-fast-forward
16 * @see       https://datatracker.ietf.org/doc/html/rfc2119
17 */
18
19namespace FastForward\Defer\EventDispatcher\Listener;
20
21use FastForward\Defer\EventDispatcher\Event\DeferredCallbackFailed;
22use Psr\Log\LoggerInterface;
23
24/**
25 * Listener that logs failed deferred callback executions using a PSR-3 compatible logger.
26 *
27 * This listener MUST be used to log all deferred callback failures. It SHALL log detailed information about the exception, callback, and arguments. This class MUST NOT throw exceptions during logging.
28 */
29final readonly class LogDeferredCallbackFailure
30{
31    /**
32     * Constructs a new LogDeferredCallbackFailure listener.
33     *
34     * @param LoggerInterface $logger the PSR-3 logger to use for logging failures
35     */
36    public function __construct(
37        private LoggerInterface $logger
38    ) {}
39
40    /**
41     * Handles the DeferredCallbackFailed event by logging the failure.
42     *
43     * This method MUST log the exception details and callback information. It MUST NOT throw exceptions.
44     *
45     * @param DeferredCallbackFailed $event the event representing the callback failure
46     *
47     * @return void
48     */
49    public function __invoke(DeferredCallbackFailed $event): void
50    {
51        $this->logger->error(
52            'Deferred callback failed: {exception_class}: {message}',
53            [
54                'exception_class' => $event->throwable::class,
55                'message' => $event->throwable->getMessage(),
56                'file' => $event->throwable->getFile(),
57                'line' => $event->throwable->getLine(),
58                'callback' => $event->callback,
59                'callback_arguments' => $event->arguments,
60                'exception' => $event->throwable,
61            ]
62        );
63    }
64}