Skip to content
This repository has been archived by the owner on Mar 22, 2023. It is now read-only.

Commit

Permalink
Merge pull request #30 from ollietb/console
Browse files Browse the repository at this point in the history
Add error notifier to console commands
  • Loading branch information
benji07 committed Oct 24, 2014
2 parents 059a1a4 + 59feef9 commit fb06809
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 14 deletions.
81 changes: 68 additions & 13 deletions Listener/Notifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
namespace Elao\ErrorNotifierBundle\Listener;

use \Swift_Mailer;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Templating\EngineInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\HttpKernel\Exception\FlattenException;

/**
Expand Down Expand Up @@ -39,6 +44,8 @@ class Notifier
private $reportWarnings = false;
private $reportErrors = false;
private $repeatTimeout = false;
private $command;
private $commandInput;

private static $tmpBuffer = null;

Expand Down Expand Up @@ -94,6 +101,22 @@ public function onKernelException(GetResponseForExceptionEvent $event)
}
}

/**
* Handle the event
*
* @param ConsoleExceptionEvent $event event
*/
public function onConsoleException(ConsoleExceptionEvent $event)
{
$exception = $event->getException();

$sendMail = !in_array(get_class($exception), $this->ignoredClasses);

if ($sendMail === true) {
$this->createMailAndSend($exception, null, null, $this->command, $this->commandInput);
}
}

/**
* Once we have the request we can use it to show debug details in the email
*
Expand All @@ -111,18 +134,40 @@ public function onKernelRequest(GetResponseEvent $event)

$this->request = $event->getRequest();

// set_error_handler and register_shutdown_function can be triggered on
// both warnings and errors
set_error_handler(array($this, 'handlePhpError'), E_ALL);
$this->setErrorHandlers();
}
}

/**
* @param ConsoleCommandEvent $event
*/
public function onConsoleCommand(ConsoleCommandEvent $event)
{
$this->request = null;

// From PHP Documentation: the following error types cannot be handled with
// a user defined function using set_error_handler: *E_ERROR*, *E_PARSE*, *E_CORE_ERROR*, *E_CORE_WARNING*,
// *E_COMPILE_ERROR*, *E_COMPILE_WARNING*
// That is we need to use also register_shutdown_function()
register_shutdown_function(array($this, 'handlePhpFatalErrorAndWarnings'));
$this->command = $event->getCommand();
$this->commandInput = $event->getInput();

if ($this->reportErrors || $this->reportWarnings) {
self::_reserveMemory();

$this->setErrorHandlers();
}
}

protected function setErrorHandlers()
{
// set_error_handler and register_shutdown_function can be triggered on
// both warnings and errors
set_error_handler(array($this, 'handlePhpError'), E_ALL);

// From PHP Documentation: the following error types cannot be handled with
// a user defined function using set_error_handler: *E_ERROR*, *E_PARSE*, *E_CORE_ERROR*, *E_CORE_WARNING*,
// *E_COMPILE_ERROR*, *E_COMPILE_WARNING*
// That is we need to use also register_shutdown_function()
register_shutdown_function(array($this, 'handlePhpFatalErrorAndWarnings'));
}

/**
* @see http://php.net/set_error_handler
*
Expand All @@ -145,7 +190,7 @@ public function handlePhpError($level, $message, $file, $line, $errcontext)

$exception = new \ErrorException(sprintf('%s: %s in %s line %d', $this->getErrorString($level), $message, $file, $line), 0, $level, $file, $line);

$this->createMailAndSend($exception, $this->request, $errcontext);
$this->createMailAndSend($exception, $this->request, $errcontext, $this->command, $this->commandInput);

// in order not to bypass the standard PHP error handler
return false;
Expand Down Expand Up @@ -177,7 +222,7 @@ public function handlePhpFatalErrorAndWarnings()

if (in_array($lastError['type'], $errors)) {
$exception = new \ErrorException(sprintf('%s: %s in %s line %d', @$this->getErrorString(@$lastError['type']), @$lastError['message'], @$lastError['file'], @$lastError['line']), @$lastError['type'], @$lastError['type'], @$lastError['file'], @$lastError['line']);
$this->createMailAndSend($exception, $this->request);
$this->createMailAndSend($exception, $this->request, null, $this->command, $this->commandInput);
}
}

Expand Down Expand Up @@ -215,8 +260,10 @@ public function getErrorString($errorNo)
* @param ErrorException $exception
* @param Request $request
* @param array $context
* @param Command $command
* @param InputInterface $commandInput
*/
public function createMailAndSend($exception, $request, $context = null)
public function createMailAndSend($exception, Request $request = null, $context = null, Command $command = null, InputInterface $commandInput = null)
{
if (!$exception instanceof FlattenException) {
$exception = FlattenException::create($exception);
Expand All @@ -229,10 +276,18 @@ public function createMailAndSend($exception, $request, $context = null)
'exception' => $exception,
'request' => $request,
'status_code' => $exception->getCode(),
'context' => $context
'context' => $context,
'command' => $command,
'command_input' => $commandInput
));

$subject = '[' . $request->headers->get('host') . '] Error ' . $exception->getStatusCode() . ': ' . $exception->getMessage();
if($this->request) {
$subject = '[' . $request->headers->get('host') . '] Error ' . $exception->getStatusCode() . ': ' . $exception->getMessage();
} elseif($this->command) {
$subject = '[' . $this->command->getName() . '] Error ' . $exception->getStatusCode() . ': ' . $exception->getMessage();
} else {
$subject = 'Error ' . $exception->getStatusCode() . ': ' . $exception->getMessage();
}

if (function_exists('mb_substr')) {
$subject = mb_substr($subject, 0, 255);
Expand Down
2 changes: 2 additions & 0 deletions Resources/config/services.xml
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
<service id="elao.error_notifier.listener" class="%elao.error_notifier.listener.class%">
<tag name="kernel.event_listener" event="kernel.exception" method="onKernelException" priority="0"/>
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="0"/>
<tag name="kernel.event_listener" event="console.exception" method="onConsoleException" priority="0"/>
<tag name="kernel.event_listener" event="console.command" method="onConsoleCommand" priority="0"/>
<argument type="service" id="mailer" />
<argument type="service" id="templating" />
<argument>%kernel.cache_dir%</argument>
Expand Down
60 changes: 59 additions & 1 deletion Resources/views/mail.html.twig
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,10 @@
<strong>Generated at: </strong> {{ "now"|date("d-m-Y H:i:s") }} <br />
<strong>Class name: </strong> {{ exception.class }} <br />
<strong>Message: </strong> {{ exception.message }} <br />
<strong>Uri: </strong> {{ request.uri }} <br />
{% if request %}<strong>Uri: </strong> {{ request.uri }} <br />{% endif %}
{% if command %}
<strong>Command:</strong> {{ command.name }}<br>
{% endif %}
</td>
</tr>
</table>
Expand Down Expand Up @@ -381,6 +384,59 @@
<td style="height: 20px;"></td>
</tr>
</table>
{% if command_input %}
{% if command_input.options|length %}
{#-- Command Options Block --#}
<table style="background: #fff; margin: 0 0 20px 0; width: 100%;">
<tr>
<td>
<h4>Command Options</h4>
<table>
<tr>
<th>Variable</th>
<th>Value</th>
</tr>
{% for key, value in command_input.options %}
<tr>
<th style="border-top: 1px solid #999; vertical-align: top;"><pre>{{ key }} =</pre></th>
<td style="border-top: 1px solid #999">{{ value|dumpy(2) }}</td>
</tr>
{% endfor %}
</table>
</td>
</tr>
</table>
{% endif %}
{% if command_input.arguments|length %}
{#-- Command Arguments Block --#}
<table style="background: #fff; margin: 0 0 20px 0; width: 100%;">
<tr>
<td>

<h4>Command Arguments</h4>
<table>

<tr>
<th>Variable</th>
<th>Value</th>
</tr>
{% for key, value in command_input.arguments %}
<tr>
<th style="border-top: 1px solid #999; vertical-align: top;"><pre>{{ key }} =</pre></th>
<td style="border-top: 1px solid #999">{{ value|dumpy(2) }}</td>
</tr>
{% endfor %}
</table>
</td>
</tr>
</table>
{% endif %}
<table>
<tr>
<td style="height: 20px;"></td>
</tr>
</table>
{% endif %}
{% if context is defined %}
{#-- Variables Parameters Block --#}
<table style="background: #fff; margin: 0 0 20px 0; width: 100%;">
Expand Down Expand Up @@ -416,6 +472,7 @@
</tr>
</table>
{% endif %}
{% if request %}
{#-- Request GET Parameters Block --#}
<table style="background: #fff; margin: 0 0 20px 0; width: 100%;">
<tr>
Expand Down Expand Up @@ -574,6 +631,7 @@
<td style="height: 20px;"></td>
</tr>
</table>
{% endif %}

</div>
</div>
Expand Down

0 comments on commit fb06809

Please sign in to comment.