Skip to content

Commit

Permalink
improved logging and exception handling
Browse files Browse the repository at this point in the history
  • Loading branch information
John Pancoast committed Apr 20, 2014
1 parent 3da2dec commit c1e35f5
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 15 deletions.
23 changes: 16 additions & 7 deletions src/AbstractCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ abstract class AbstractCommand extends ConsoleCommand
*/
protected $options = [];

/**
* @var Logger The monolog logger
*
* @access private
*/
private $logger;

/**
* Get command name
*
Expand Down Expand Up @@ -192,14 +199,16 @@ protected function init(InputInterface $input, OutputInterface $output)
*/
protected function buildLogger()
{
if (!isset($this->options['log_file'])) {
throw new \Exception('To build the lib\'s logger, we need a log file to log to.');
}
if (!$this->logger) {
if (!isset($this->options['log_file'])) {
throw new \Exception('To build the lib\'s logger, we need a log file to log to.');
}

$logger = new Logger('shideon_tasker_main');
$logger->pushHandler(new StreamHandler($this->options['log_file'], $this->options['log_level'] ?: Logger::INFO));;
$this->logger = new Logger('shideon_tasker_main');
$this->logger->pushHandler(new StreamHandler($this->options['log_file'], $this->options['log_level'] ?: Logger::INFO));;
}

return $logger;
return $this->logger;
}

/**
Expand Down Expand Up @@ -245,7 +254,7 @@ protected function validateOptions(array $requiredOptions = [])
{
foreach ($requiredOptions as $key) {
if (!array_key_exists($key, $this->options) || empty($this->options[$key])) {
throw new Exception\RequiredCommandOptionException("Must set the --$key option.");
throw new Exception\RequiredCommandOptionException("Must set the --$key option.", $key);
}
}
}
Expand Down
27 changes: 20 additions & 7 deletions src/Command/RunTaskCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,12 @@ protected function getConfigOptions()
*/
protected function getRequiredOptions()
{
return array_merge(parent::getRequiredOptions(), ['task_class', 'task_name']);
$options = array_merge(parent::getRequiredOptions(), ['task_class', 'task_name']);

$logger = $this->buildLogger();
$logger->log(Logger::DEBUG, 'RunTaskCommand required command options: '.print_r($options, true));

return $options;
}

/**
Expand All @@ -115,13 +120,21 @@ protected function execute(InputInterface $input, OutputInterface $output)
->setCommand($this->options['task_command'])
->setCommandArgs((array)json_decode($this->options['task_command_arguments'], true))
->run();
} catch (RequiredCommandOptionException $e) {
// we cannot log these exceptions since we've
// failed at option validation and we need options
// for a logger to be created.
throw $e;
} catch (\Exception $e) {
$logger->log(Logger::CRITICAL, "Running task '".$this->options['task_name']."' encountered exception in ".get_class($this), [$e, 'trace' => $e->getTraceAsString()]);
// if we don't have a logger (due to exception being thrown before
// it's instantiatied) then attempt to build one. ignore its
// exceptions.
if (!isset($logger) || !($logger instanceof Logger)) {
try {
$logger = $this->buildLogger();
} catch (\Exception $e) {
// ignore
}
}

if (isset($logger) && $logger instanceof Logger) {
$logger->log(Logger::CRITICAL, "Running task '".$this->options['task_name']."' encountered exception in ".get_class($this), [$e, 'trace' => $e->getTraceAsString()]);
}

throw $e;
}
Expand Down
53 changes: 52 additions & 1 deletion src/Exception/RequiredCommandOptionException.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,55 @@
*
* @author John Pancoast <[email protected]>
*/
class RequiredCommandOptionException extends \Exception {}
class RequiredCommandOptionException extends \Exception
{
/**
* @var string The key that failed
*
* @access private
*/
private $key;

/**
* Override parent constructor.
*
* Note that we allow a string for our second param for the key that failed
* but we call the parent without the second param which is
* (long)code in exception)
*
* @access public
* {@inheritDoc}
* @param string $message The exception message
* @param string $key The key that failed.
*/
public function __construct($message, $key)
{
$this->setKey($key);
parent::__construct($message);
}

/**
* Set the key that failed
*
* @access public
* @param string $key The key that failed.
* @return self
*/
public function setKey($key)
{
$this->key = $key;

return $this;
}

/**
* Get the key that failed
*
* @access public
* @return string
*/
public function getKey()
{
return $this->key;
}
}

0 comments on commit c1e35f5

Please sign in to comment.