Files
michaelschiemer/src/Framework/Mail/Commands/SendEmailBatchCommandHandler.php
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

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,
]);
}
}
}