Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
ErrorEvent
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
6 / 6
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 isPropagationStopped
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 stopPropagation
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEvent
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getListener
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getThrowable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of php-fast-forward/event-dispatcher.
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) 2025-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/event-dispatcher
15 * @see       https://github.com/php-fast-forward
16 * @see       https://datatracker.ietf.org/doc/html/rfc2119
17 */
18
19namespace FastForward\EventDispatcher\Event;
20
21use Throwable;
22use Exception;
23use Psr\EventDispatcher\StoppableEventInterface;
24
25/**
26 * Represent a listener failure as a dispatchable event.
27 *
28 * The dispatcher emits this event when a listener throws while handling another event.
29 */
30 class ErrorEvent extends Exception implements StoppableEventInterface
31{
32    /**
33     * Listener that raised the throwable.
34     *
35     * @var callable
36     */
37    private $listener;
38
39    /**
40     * Create an error event from a failed listener invocation.
41     *
42     * @param object $event original event being dispatched
43     * @param callable $listener listener that raised the throwable
44     * @param Throwable $throwable throwable raised by the listener
45     * @param bool $propagationStopped initial propagation state for this error event
46     */
47    public function __construct(
48        private  object $event,
49        callable $listener,
50        Throwable $throwable,
51        private bool $propagationStopped = false
52    ) {
53        parent::__construct($throwable->getMessage(), $throwable->getCode(), $throwable);
54        $this->listener = $listener;
55    }
56
57    /**
58     * Determine whether propagation for this error event has been stopped.
59     *
60     * @return bool whether propagation is currently stopped
61     */
62    public function isPropagationStopped(): bool
63    {
64        return $this->propagationStopped;
65    }
66
67    /**
68     * Mark this error event as stopped.
69     */
70    public function stopPropagation(): void
71    {
72        $this->propagationStopped = true;
73    }
74
75    /**
76     * Get the original event that was being dispatched.
77     *
78     * @return object event instance associated with the listener failure
79     */
80    public function getEvent(): object
81    {
82        return $this->event;
83    }
84
85    /**
86     * Get the listener that raised the throwable.
87     *
88     * @return callable listener associated with this error event
89     */
90    public function getListener(): callable
91    {
92        return $this->listener;
93    }
94
95    /**
96     * Get the throwable that caused this error event.
97     *
98     * @return Throwable throwable stored as the previous exception
99     */
100    public function getThrowable(): Throwable
101    {
102        return $this->getPrevious();
103    }
104}