src/EventListener/ExceptionListener.php line 85

Open in your IDE?
  1. <?php
  2. /**
  3.  * This file is part of the AURES Frontend API package.
  4.  *
  5.  * (c) AURES HOLDING <info@aaaauto.cz>
  6.  *
  7.  */
  8. namespace App\EventListener;
  9. use Symfony\Component\Console\Event\ConsoleErrorEvent;
  10. use Symfony\Component\Console\Command\Command;
  11. use Symfony\Component\Mailer\MailerInterface;
  12. use Symfony\Component\VarDumper\Cloner\VarCloner;
  13. use Symfony\Component\VarDumper\Dumper\HtmlDumper;
  14. use Symfony\Component\Mime\Email;
  15. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  16. use Symfony\Component\Mime\Address;
  17. use App\Exception\CommandException;
  18. use Exception;
  19. use Throwable;
  20. /**
  21.  * Analize all bundle exception and fire propper actions.
  22.  *
  23.  * @author David Evdoshchenko <4341922@gmail.com>
  24.  */
  25. class ExceptionListener
  26. {
  27.     /**
  28.      * These credit will be used if you set it to non-empty.
  29.      * Otherwise will be used recepients from App services config.
  30.      *
  31.      * FROM:
  32.      * fill with (single) if you need custom 'from' for this command:
  33.      * - 'email' => 'your@mail.com',
  34.      * - 'name'  => 'Your Name'
  35.      *
  36.      * TO:
  37.      * fill with (multiple) if you need custom 'to' for this command:
  38.      * - ['email' => 'your@mail.com', 'name'  => 'Your Name']
  39.      *
  40.      * @var array
  41.      */
  42.     private array $mailRecepientsDefault = [
  43.         'from' => [],
  44.         'to'   => [],
  45.     ];
  46.     /**
  47.      * These cred will be used if none provided.
  48.      *
  49.      * @var MailerInterface
  50.      */
  51.     private MailerInterface $mailer;
  52.     /**
  53.      * These cred will be used if none provided.
  54.      *
  55.      * @var array
  56.      */
  57.     private array $mailRecepients;
  58.     /**
  59.      * Constructor
  60.      *
  61.      * @param MailerInterface $mailer         Symfony mailer.
  62.      * @param array           $mailRecepients Emails and Names.
  63.      *
  64.      * @return void
  65.      */
  66.     public function __construct(MailerInterface $mailer, array $mailRecepients)
  67.     {
  68.         $this->mailer         $mailer;
  69.         $this->mailRecepients $mailRecepients;
  70.     }
  71.     /**
  72.      * Event handler
  73.      *
  74.      * @param ConsoleErrorEvent $event Event itself.
  75.      *
  76.      * @return void
  77.      */
  78.     public function onConsoleError(ConsoleErrorEvent $event): void
  79.     {
  80.         $exception $event->getError();
  81.         $command   $event->getCommand();
  82.         if ($exception instanceof CommandException) {
  83.             $this->notifyCommandException($exception$command);
  84.         }
  85.     }
  86.     /**
  87.      * Prepare email msg and send it.
  88.      *
  89.      * @param Throwable $e       Exception
  90.      * @param Command   $command Command
  91.      *
  92.      * @return void
  93.      */
  94.     private function notifyCommandException(Throwable $eCommand $command): void
  95.     {
  96.         $cloner = new VarCloner();
  97.         $dumper = new HtmlDumper();
  98.         $class  $command::class;
  99.         $name   $command->getDefaultName();
  100.         $dump   $dumper->dump($cloner->cloneVar($e), true);
  101.         if (property_exists($command'mailRecepients')) {
  102.             $recepients $command->mailRecepients;
  103.         } else {
  104.             $recepients $this->mailRecepientsDefault;
  105.             $e = new Exception("Command {$name} within class {$class} thrown exception, but it does not realize property mailRecepients, fallback to default ones"$e->getCode(), $e);
  106.         }
  107.         $this->resolveRecipients($recepients);
  108.         $email = (new TemplatedEmail())
  109.             ->from($recepients['from'])
  110.             ->to(...$recepients['to'])
  111.             ->priority(Email::PRIORITY_HIGH)
  112.             ->subject('Runtime Exception!')
  113.             ->htmlTemplate('emails/error-log-exception.html.twig')
  114.             ->context([
  115.                 'command'   => $name,
  116.                 'exception' => $e,
  117.                 'dump'      => $dump,
  118.             ]);
  119.         $this->sendMail($email);
  120.     }
  121.     /**
  122.      * Set default recipients if none provided.
  123.      *
  124.      * @param array $recipients To and From.
  125.      *
  126.      * @return void
  127.      */
  128.     private function resolveRecipients(array &$recipients): void
  129.     {
  130.         // This ones comes from service.yaml by DI.
  131.         $defaults $this->mailRecepients['exception'];
  132.         if (empty($recipients['from'])) {
  133.             $recipients['from'] = new Address($defaults['from']['mail'], $defaults['from']['name']);
  134.         }
  135.         if (empty($recipients['to'])) {
  136.             $recipients['to'] = array_map(fn($recipient) => new Address($recipient['mail'], $recipient['name']), $defaults['to']);
  137.         }
  138.     }
  139.     /**
  140.      * Transport.
  141.      *
  142.      * @param Email $mail Mail instance.
  143.      */
  144.     private function sendMail(Email $mail): void
  145.     {
  146.         $this->mailer->send($mail);
  147.     }
  148. }