Dustin Wilson
2 years ago
5 changed files with 125 additions and 19 deletions
@ -0,0 +1,115 @@ |
|||
<?php |
|||
/** |
|||
* @license MIT |
|||
* Copyright 2022 Dustin Wilson, et al. |
|||
* See LICENSE and AUTHORS files for details |
|||
*/ |
|||
|
|||
declare(strict_types=1); |
|||
namespace MensBeam\Framework\Catcher; |
|||
use \Psr\Log\LoggerInterface; |
|||
|
|||
|
|||
class JSONHandler extends Handler { |
|||
public const CONTENT_TYPE = 'application/json'; |
|||
|
|||
/** If true the handler will output times to the output; defaults to true */ |
|||
protected bool $_outputTime = true; |
|||
/** The PHP-standard date format which to use for timestamps in output */ |
|||
protected string $_timeFormat = 'c'; |
|||
|
|||
|
|||
protected function dispatchCallback(): void { |
|||
$output = [ |
|||
'status' => (string)$this->_httpCode |
|||
]; |
|||
|
|||
$errors = []; |
|||
foreach ($this->outputBuffer as $o) { |
|||
if ($o->outputCode & self::SILENT) { |
|||
continue; |
|||
} |
|||
|
|||
$errors[] = $o->output; |
|||
} |
|||
$output['errors'] = $errors; |
|||
|
|||
$this->print(json_encode($output, \JSON_PARTIAL_OUTPUT_ON_ERROR)); |
|||
} |
|||
|
|||
protected function handleCallback(ThrowableController $controller): HandlerOutput { |
|||
$output = $this->buildThrowableArray($controller); |
|||
if ($this->_outputPrevious) { |
|||
$target = $output; |
|||
$prevController = $controller->getPrevious(); |
|||
while ($prevController) { |
|||
$prev = $this->buildThrowableArray($prevController); |
|||
$target['previous'] = $prev; |
|||
$target = $prev; |
|||
$prevController = $prevController->getPrevious(); |
|||
} |
|||
} |
|||
|
|||
if ($this->_outputBacktrace) { |
|||
$output['frames'] = $controller->getFrames(); |
|||
} |
|||
|
|||
if ($this->_outputTime && $this->_timeFormat !== '') { |
|||
$output['timestamp'] = (new \DateTime())->format($this->_timeFormat); |
|||
} |
|||
|
|||
return new HandlerOutput($this->getControlCode(), $this->getOutputCode(), $output); |
|||
} |
|||
|
|||
|
|||
|
|||
protected function log(\Throwable $throwable, string $message): void { |
|||
if ($throwable instanceof \Error) { |
|||
switch ($throwable->getCode()) { |
|||
case \E_NOTICE: |
|||
case \E_USER_NOTICE: |
|||
case \E_STRICT: |
|||
$this->_logger->notice($message); |
|||
break; |
|||
case \E_WARNING: |
|||
case \E_COMPILE_WARNING: |
|||
case \E_USER_WARNING: |
|||
case \E_DEPRECATED: |
|||
case \E_USER_DEPRECATED: |
|||
$this->_logger->warning($message); |
|||
break; |
|||
case \E_RECOVERABLE_ERROR: |
|||
$this->_logger->error($message); |
|||
break; |
|||
case \E_PARSE: |
|||
case \E_CORE_ERROR: |
|||
case \E_COMPILE_ERROR: |
|||
$this->_logger->alert($message); |
|||
break; |
|||
default: $this->_logger->critical($message); |
|||
} |
|||
} elseif ($throwable instanceof \Exception && ($throwable instanceof \PharException || $throwable instanceof \RuntimeException)) { |
|||
$this->_logger->alert($message); |
|||
} else { |
|||
$this->_logger->critical($message); |
|||
} |
|||
} |
|||
|
|||
protected function buildThrowableArray(ThrowableController $controller): array { |
|||
$throwable = $controller->getThrowable(); |
|||
$type = $throwable::class; |
|||
if ($throwable instanceof Error) { |
|||
$t = $controller->getErrorType(); |
|||
$t = ($throwable instanceof Error) ? $controller->getErrorType() : null; |
|||
$type = ($t !== null) ? "$t (" . $type . ")" : $type; |
|||
} |
|||
|
|||
return [ |
|||
'code' => $throwable->getCode(), |
|||
'file' => $throwable->getFile(), |
|||
'line' => $throwable->getLine(), |
|||
'message' => $throwable->getMessage(), |
|||
'type' => $type |
|||
]; |
|||
} |
|||
} |
Loading…
Reference in new issue