- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
108 lines
3.9 KiB
PHP
108 lines
3.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Mail\Commands;
|
|
|
|
use App\Framework\CommandBus\CommandHandler;
|
|
use App\Framework\Exception\ExceptionContext;
|
|
use App\Framework\Logging\Logger;
|
|
use App\Framework\Mail\Exceptions\SmtpException;
|
|
use App\Framework\Mail\TransportInterface;
|
|
|
|
final readonly class SendEmailBatchCommandHandler
|
|
{
|
|
public function __construct(
|
|
private TransportInterface $transport,
|
|
private Logger $logger,
|
|
) {
|
|
}
|
|
|
|
#[CommandHandler]
|
|
public function handle(SendEmailBatchCommand $command): void
|
|
{
|
|
$messageCount = $command->getMessageCount();
|
|
$successCount = 0;
|
|
$failureCount = 0;
|
|
$errors = [];
|
|
|
|
$this->logger->info('Starting batch email sending', [
|
|
'message_count' => $messageCount,
|
|
'transport' => $this->transport->getName(),
|
|
]);
|
|
|
|
foreach ($command->messages as $index => $message) {
|
|
try {
|
|
$result = $this->transport->send($message);
|
|
|
|
if ($result->isSuccess()) {
|
|
$successCount++;
|
|
|
|
$this->logger->debug('Batch email sent successfully', [
|
|
'batch_index' => $index,
|
|
'message_id' => $result->getMessageId(),
|
|
'to' => $message->to->toString(),
|
|
'subject' => $message->subject,
|
|
]);
|
|
} else {
|
|
$failureCount++;
|
|
$errorMessage = "Email {$index} failed: " . $result->getError();
|
|
$errors[] = $errorMessage;
|
|
|
|
$this->logger->warning('Batch email failed', [
|
|
'batch_index' => $index,
|
|
'error' => $result->getError(),
|
|
'metadata' => $result->getMetadata(),
|
|
'to' => $message->to->toString(),
|
|
'subject' => $message->subject,
|
|
]);
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
$failureCount++;
|
|
$errorMessage = "Email {$index} exception: " . $e->getMessage();
|
|
$errors[] = $errorMessage;
|
|
|
|
$this->logger->error('Batch email exception', [
|
|
'batch_index' => $index,
|
|
'exception_class' => get_class($e),
|
|
'exception_message' => $e->getMessage(),
|
|
'to' => $message->to->toString(),
|
|
'subject' => $message->subject,
|
|
]);
|
|
}
|
|
}
|
|
|
|
$this->logger->info('Batch email sending completed', [
|
|
'total_messages' => $messageCount,
|
|
'successful' => $successCount,
|
|
'failed' => $failureCount,
|
|
'success_rate' => $messageCount > 0 ? round(($successCount / $messageCount) * 100, 2) : 0,
|
|
]);
|
|
|
|
// If all emails failed, throw an exception to trigger retry
|
|
if ($failureCount === $messageCount && $messageCount > 0) {
|
|
throw new SmtpException(
|
|
message: "All {$messageCount} emails in batch failed to send",
|
|
context: ExceptionContext::forOperation('send_email_batch', 'mail')
|
|
->withData([
|
|
'total_messages' => $messageCount,
|
|
'failed_messages' => $failureCount,
|
|
'errors' => $errors,
|
|
'transport' => $this->transport->getName(),
|
|
])
|
|
);
|
|
}
|
|
|
|
// If more than 50% failed, log a warning but don't throw (partial success)
|
|
if ($failureCount > ($messageCount / 2)) {
|
|
$this->logger->warning('High failure rate in batch email sending', [
|
|
'total_messages' => $messageCount,
|
|
'failed_messages' => $failureCount,
|
|
'failure_rate' => round(($failureCount / $messageCount) * 100, 2),
|
|
'errors' => $errors,
|
|
]);
|
|
}
|
|
}
|
|
}
|