-
Notifications
You must be signed in to change notification settings - Fork 0
/
RemoteEventHandler.php
62 lines (55 loc) · 1.92 KB
/
RemoteEventHandler.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php
namespace App\Stripe;
use Doctrine\DBAL\Connection;
use Stripe\Event;
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Messenger\Exception\RecoverableExceptionInterface;
use Symfony\Component\Messenger\Exception\UnrecoverableExceptionInterface;
use Symfony\Component\Messenger\Exception\UnrecoverableMessageHandlingException;
use Webmozart\Assert\Assert;
/**
* TODO: try out multiple handlers for RemoteEvent
*/
#[AsMessageHandler]
final readonly class RemoteEventHandler
{
public function __construct(
#[TaggedIterator('stripe.remote_event_handler')]
/**
* @var iterable<StripeEventAware>
*/
private iterable $handlers,
private Connection $connection,
) {
}
/**
* @throws RecoverableExceptionInterface
* @throws UnrecoverableExceptionInterface
* @throws \Throwable
*/
public function __invoke(RemoteEvent $message): void
{
try {
$event = Event::constructFrom(
(array) json_decode($message->payload, true, 512, JSON_THROW_ON_ERROR)
);
} catch (\JsonException $e) {
throw new UnrecoverableMessageHandlingException('Invalid JSON payload', 0, $e);
}
$handlers = $this->handlers;
Assert::allIsInstanceOf($handlers, StripeEventAware::class);
/**
* All or nothing approach.
* When one handler fails, the whole transaction is rolled back.
*
* TODO: consider handlers that modify state outside the database.
* e.g. what happens when a handler updates a search index etc...
*/
$this->connection->transactional(function () use ($event, $handlers) {
foreach ($handlers as $handler) {
$handler->handleStripeEvent($event);
}
});
}
}