1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Console\EventListener;
13
14use Psr\Log\LoggerInterface;
15use Symfony\Component\Console\ConsoleEvents;
16use Symfony\Component\Console\Event\ConsoleErrorEvent;
17use Symfony\Component\Console\Event\ConsoleEvent;
18use Symfony\Component\Console\Event\ConsoleTerminateEvent;
19use Symfony\Component\EventDispatcher\EventSubscriberInterface;
20
21/**
22 * @author James Halsall <james.t.halsall@googlemail.com>
23 * @author Robin Chalas <robin.chalas@gmail.com>
24 */
25class ErrorListener implements EventSubscriberInterface
26{
27    private $logger;
28
29    public function __construct(LoggerInterface $logger = null)
30    {
31        $this->logger = $logger;
32    }
33
34    public function onConsoleError(ConsoleErrorEvent $event)
35    {
36        if (null === $this->logger) {
37            return;
38        }
39
40        $error = $event->getError();
41
42        if (!$inputString = $this->getInputString($event)) {
43            $this->logger->error('An error occurred while using the console. Message: "{message}"', ['exception' => $error, 'message' => $error->getMessage()]);
44
45            return;
46        }
47
48        $this->logger->error('Error thrown while running command "{command}". Message: "{message}"', ['exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()]);
49    }
50
51    public function onConsoleTerminate(ConsoleTerminateEvent $event)
52    {
53        if (null === $this->logger) {
54            return;
55        }
56
57        $exitCode = $event->getExitCode();
58
59        if (0 === $exitCode) {
60            return;
61        }
62
63        if (!$inputString = $this->getInputString($event)) {
64            $this->logger->debug('The console exited with code "{code}"', ['code' => $exitCode]);
65
66            return;
67        }
68
69        $this->logger->debug('Command "{command}" exited with code "{code}"', ['command' => $inputString, 'code' => $exitCode]);
70    }
71
72    public static function getSubscribedEvents()
73    {
74        return [
75            ConsoleEvents::ERROR => ['onConsoleError', -128],
76            ConsoleEvents::TERMINATE => ['onConsoleTerminate', -128],
77        ];
78    }
79
80    private static function getInputString(ConsoleEvent $event)
81    {
82        $commandName = $event->getCommand() ? $event->getCommand()->getName() : null;
83        $input = $event->getInput();
84
85        if (method_exists($input, '__toString')) {
86            if ($commandName) {
87                return str_replace(["'$commandName'", "\"$commandName\""], $commandName, (string) $input);
88            }
89
90            return (string) $input;
91        }
92
93        return $commandName;
94    }
95}
96