Completed
Push — master ( 69e5dd...2e54cb )
by Tomáš
02:36
created

attachRecordingCallbackToEventbus()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 1
crap 1
1
<?php declare(strict_types = 1);
2
3
namespace TomCizek\ResponseRecorder\Application;
4
5
use Prooph\Common\Event\ActionEvent;
6
use Prooph\Common\Messaging\DomainEvent;
7
use Prooph\ServiceBus\EventBus;
8
use Prooph\ServiceBus\Exception\CommandDispatchException;
9
use Prooph\ServiceBus\MessageBus;
10
use Psr\Log\LoggerInterface;
11
use Throwable;
12
use TomCizek\ResponseRecorder\Application\ResponseRecorder\BasicMutationResponse;
13
use TomCizek\ResponseRecorder\Application\ResponseRecorder\MutationResponse\BasicMutationResponseBuilder;
14
use TomCizek\ResponseRecorder\Application\ResponseRecorder\MutationResponse\ErrorCollection\GenericShowableMutationError;
15
use TomCizek\ResponseRecorder\DomainModel\ShowableTranslatableDomainException;
16
17
final class ResponseRecorder
18
{
19
	public const FATAL_ERROR_MESSAGE = 'fatal_error_occured_logged';
20
21
	/** @var EventBus */
22
	private $eventBus;
23
24
	/** @var LoggerInterface */
25
	private $logger;
26
27 9
	public function __construct(EventBus $eventBus, LoggerInterface $logger)
28
	{
29 9
		$this->eventBus = $eventBus;
30 9
		$this->logger = $logger;
31 9
	}
32
33 9
	public function recordOn($callback): BasicMutationResponse
34
	{
35 9
		$responseBuilder = BasicMutationResponseBuilder::create();
36
37 9
		$this->attachRecordingCallbackToEventbus($responseBuilder);
38
39
		try {
40 9
			$callback();
41 5
		} catch (CommandDispatchException $exception) {
42 2
			$this->handleCommandDispatchException($exception, $responseBuilder);
43 3
		} catch (ShowableTranslatableDomainException $exception) {
44 1
			$this->handleShowableException($exception, $responseBuilder);
45 2
		} catch (Throwable $exception) {
46 2
			$this->handleFatalException($exception, $responseBuilder);
47
		}
48
49 9
		return $responseBuilder->build();
50
	}
51
52 9
	private function attachRecordingCallbackToEventbus(
53
		BasicMutationResponseBuilder $responseBuilder
54
	): void {
55 9
		$this->eventBus->attach(
56 9
			EventBus::EVENT_DISPATCH,
57 9
			$this->getRecordingCallback($responseBuilder),
58 9
			-1000
59
		);
60 9
	}
61
62
	private function getRecordingCallback(BasicMutationResponseBuilder $responseBuilder): \Closure
63
	{
64 9
		return function (ActionEvent $actionEvent) use ($responseBuilder): void {
65 4
			$event = $actionEvent->getParam(MessageBus::EVENT_PARAM_MESSAGE);
66 4
			if (!$event instanceof DomainEvent) {
67 1
				return;
68
			}
69 3
			$responseBuilder->addDomainEvent($event);
70 9
		};
71
	}
72
73 2
	private function handleCommandDispatchException(
74
		CommandDispatchException $exception,
75
		BasicMutationResponseBuilder $responseBuilder
76
	): void {
77 2
		$previous = $exception->getPrevious();
78 2
		if ($previous instanceof ShowableTranslatableDomainException) {
79 1
			$this->handleShowableException($previous, $responseBuilder);
80
		} else {
81 1
			$this->handleFatalException($exception, $responseBuilder);
82
		}
83 2
	}
84
85 2
	protected function handleShowableException(
86
		ShowableTranslatableDomainException $exception,
87
		BasicMutationResponseBuilder $responseBuilder
88
	): void {
89 2
		$responseBuilder->addError(
90 2
			GenericShowableMutationError::create(
91 2
				$exception->getMessage(),
92 2
				$exception->getMessageParameters()
93
			)
94
		);
95 2
	}
96
97 3
	protected function handleFatalException(
98
		Throwable $exception,
99
		BasicMutationResponseBuilder $responseBuilder
100
	): void {
101 3
		$this->logFatalError($exception);
102
103 3
		$responseBuilder->addError(
104 3
			GenericShowableMutationError::create(
105 3
				self::FATAL_ERROR_MESSAGE
106
			)
107
		);
108 3
	}
109
110 3
	private function logFatalError(
111
		Throwable $exception
112
	): void {
113 3
		$this->logger->error($exception);
114 3
	}
115
}
116