FIX: Show detailed errors on CLI for live environments

API: Add HTTPOutputHandler::setCLIFormatter

Fixes https://github.com/silverstripe/silverstripe-framework/issues/6835

This provides detailed errors (but not warnings or notices) in CLI calls
on live environments.

It does this by adding a 2nd argument to our output handler,
CliFormatter. This formatter will be used when Director::is_cli() is
true.
This commit is contained in:
Sam Minnee 2017-04-24 16:38:13 +12:00
parent 5a7c6d4f60
commit 4c772c80c3
3 changed files with 65 additions and 17 deletions

View File

@ -37,8 +37,9 @@ SilverStripe\Core\Injector\Injector:
constructor:
- "error"
properties:
Formatter: %$FriendlyErrorFormatter
FriendlyErrorFormatter:
Formatter: %$SilverStripe\Logging\DebugViewFriendlyErrorFormatter
CLIFormatter: %$SilverStripe\Logging\DetailedErrorFormatter
SilverStripe\Logging\DebugViewFriendlyErrorFormatter:
class: SilverStripe\Logging\DebugViewFriendlyErrorFormatter
properties:
Title: "There has been an error"

View File

@ -107,7 +107,7 @@ To send emails, you can use Monolog's [NativeMailerHandler](https://github.com/S
- error
properties:
ContentType: text/html
Formatter: %$SilverStripe\Framework\Logging\DetailedErrorFormatter
Formatter: %$SilverStripe\Logging\DetailedErrorFormatter
The first section 4 lines passes a new handler to `Logger::pushHandler()` from the named service `MailHandler`. The
next 10 lines define what the service is.
@ -157,11 +157,12 @@ non-dev.
calls:
- [ pushHandler, [ %$DisplayErrorHandler ]]
DisplayErrorHandler:
class: SilverStripe\Framework\Logging\HTTPOutputHandler
class: SilverStripe\Logging\HTTPOutputHandler
constructor:
- "notice"
properties:
Formatter: %$SilverStripe\Framework\Logging\DetailedErrorFormatter
Formatter: %$SilverStripe\Logging\DetailedErrorFormatter
CLIFormatter: %$SilverStripe\Logging\DetailedErrorFormatter
---
Name: live-errors
Except:
@ -181,13 +182,13 @@ non-dev.
Formatter: %$Monolog\Formatter\HtmlFormatter
ContentType: text/html
DisplayErrorHandler:
class: SilverStripe\Framework\Logging\HTTPOutputHandler
class: SilverStripe\Logging\HTTPOutputHandler
constructor:
- "error"
properties:
Formatter: %$FriendlyErrorFormatter
FriendlyErrorFormatter:
class: SilverStripe\Framework\Logging\DebugViewFriendlyErrorFormatter
Formatter: %$SilverStripe\Logging\DebugViewFriendlyErrorFormatter
SilverStripe\Logging\DebugViewFriendlyErrorFormatter:
class: SilverStripe\Logging\DebugViewFriendlyErrorFormatter
properties:
Title: "There has been an error"
Body: "The website server has not been able to respond to your request"
@ -236,21 +237,21 @@ be ignored.
### Replacing the error handler
The class `SilverStripe\Framework\Logging\MonologLoader` is responsible for loading performing Monolog-specific
configuration. It does a number of things:
The Injector service `ErrorHandler` is responsible for initialising the error handler. By default it
* Create a `Monolog\ErrorHandler` object.
* Register the registered service `Logger` against it, to start the error handler.
* If `Logger` has a `pushHandler()` method, pass every object defined by `ErrorHandler.handlers` into it, one at a time.
* Create a `SilverStripe\Logging\MonologErrorHandler` object.
* Attach the registered service `Psr\Log\LoggerInterface` to it, to start the error handler.
Core.php will call `start()` on this method, to start the error handler.
This error handler is flexible enough to work with any PSR-3 logging implementation, but sometimes you will want to use
another. To replace this, you should registered a new service, `ErrorHandlerLoader`. For example:
SilverStripe\Core\Injector\Injector:
ErrorHandlerLoader:
ErrorHandler:
class: MyApp\CustomErrorHandlerLoader
You should register something `Callable`, for example a class with an `__invoke()` method.
You should register something with a `start()` method.
## Differences from SilverStripe 3

View File

@ -3,8 +3,10 @@
namespace SilverStripe\Logging;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
use SilverStripe\Control\HTTPResponse;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Formatter\FormatterInterface;
/**
* Output the error to the browser, with the given HTTP status code.
@ -23,6 +25,11 @@ class HTTPOutputHandler extends AbstractProcessingHandler
*/
private $statusCode = 500;
/**
* @var FormatterInterface
*/
private $cliFormatter = null;
/**
* Get the mime type to use when displaying this error.
*
@ -38,7 +45,7 @@ class HTTPOutputHandler extends AbstractProcessingHandler
* Default text/html
*
* @param string $contentType
* @return $this
* @return HTTPOutputHandler Return $this to allow chainable calls
*/
public function setContentType($contentType)
{
@ -69,6 +76,45 @@ class HTTPOutputHandler extends AbstractProcessingHandler
return $this;
}
/**
* Set a formatter to use if Director::is_cli() is true
*
* @param $cliFormatter
* @return HTTPOutputHandler Return $this to allow chainable calls
*/
public function setCLIFormatter(FormatterInterface $cliFormatter)
{
$this->cliFormatter = $cliFormatter;
return $this;
}
/**
* Return the formatter use if Director::is_cli() is true
* If none has been set, null is returned, and the getFormatter() result will be used instead
*
* @return FormatterInterface
*/
public function getCLIFormatter()
{
return $this->cliFormatter;
}
/**
* Return the formatter to use in this case.
* May be the getCliFormatter() value if one is provided and Director::is_cli() is true.
*
* @return FormatterInterface
*/
public function getFormatter()
{
if (Director::is_cli() && ($cliFormatter = $this->getCLIFormatter())) {
return $cliFormatter;
}
return parent::getFormatter();
}
/**
* @param array $record
* @return bool