Skip to content
41 changes: 36 additions & 5 deletions src/Illuminate/Foundation/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ class Handler implements ExceptionHandlerContract
*/
protected $contextCallbacks = [];

/**
* The exception currently being reported.
*
* @var \Throwable|null
*/
protected ?Throwable $currentlyReporting = null;

/**
* The callbacks that should be used during rendering.
*
Expand Down Expand Up @@ -398,11 +405,25 @@ protected function reportThrowable(Throwable $e): void

$level = $this->mapLogLevel($e);

$context = $this->buildExceptionContext($e);
$originallyReporting = $this->currentlyReporting;
$this->currentlyReporting = $e;
try {
$context = $this->buildExceptionContext($e);

method_exists($logger, $level)
? $logger->{$level}($e->getMessage(), $context)
: $logger->log($level, $e->getMessage(), $context);
method_exists($logger, $level)
? $logger->{$level}($e->getMessage(), $context)
: $logger->log($level, $e->getMessage(), $context);
} finally {
$this->currentlyReporting = $originallyReporting;
}
}

/**
* Determine if a given exception is being reported.
*/
public function isReporting(Throwable $e): bool
{
return $this->currentlyReporting === $e;
}

/**
Expand Down Expand Up @@ -534,12 +555,22 @@ public function stopIgnoring(array|string $exceptions)
protected function buildExceptionContext(Throwable $e)
{
return array_merge(
$this->exceptionContext($e),
$this->buildContextForException($e),
$this->context(),
['exception' => $e]
);
}

/**
* Creates the context for an exception.
*
* @return array<array-key, mixed>
*/
public function buildContextForException(Throwable $e)
{
return $this->exceptionContext($e);
}

/**
* Get the default exception context variables for logging.
*
Expand Down
44 changes: 44 additions & 0 deletions src/Illuminate/Log/Formatters/JsonFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Illuminate\Log\Formatters;

use Illuminate\Container\Container;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Monolog\Formatter\JsonFormatter as MonologJsonFormatter;
use Throwable;

class JsonFormatter extends MonologJsonFormatter
{
#[\Override]
protected function normalizeException(Throwable $e, int $depth = 0): array
{
$response = parent::normalizeException($e, $depth);

try {
$handler = Container::getInstance()->make(ExceptionHandler::class);
} catch (Throwable) {
return $response;
}

if ((! method_exists($handler, 'isReporting')) || ! $handler->isReporting($e)) {
if (method_exists($handler, 'buildContextForException')
&& (is_array($normalizedHandlerExceptionContext = $this->normalize($handler->buildContextForException($e), $depth + 1)))
) {
$response = array_merge(
$normalizedHandlerExceptionContext,
$response
);
} elseif (method_exists($e, 'context')) {
$exceptionContext = $this->normalize($e->context(), $depth + 1);
if (is_array($exceptionContext)) {
$response = array_merge(
$exceptionContext,
$response
);
}
}
}

return $response;
}
}
Loading