Skip to content

Commit e3b339e

Browse files
committed
feat: provide context when reporting exception to psr log
1 parent 229c0d2 commit e3b339e

2 files changed

Lines changed: 78 additions & 1 deletion

File tree

src/Infrastructure/ExceptionReporter/PsrLogExceptionReporter.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
namespace CloudCreativity\Modules\Infrastructure\ExceptionReporter;
1414

1515
use CloudCreativity\Modules\Contracts\Application\Ports\Driven\ExceptionReporter;
16+
use CloudCreativity\Modules\Contracts\Toolkit\Loggable\ContextProvider;
1617
use Psr\Log\LoggerInterface;
1718
use Throwable;
1819

@@ -34,7 +35,25 @@ public function report(Throwable $ex): void
3435
{
3536
$this->logger->error(
3637
$ex->getMessage() ?: 'Unexpected error: ' . $ex::class,
37-
['exception' => $ex],
38+
[...$this->context($ex), 'exception' => $ex],
3839
);
3940
}
41+
42+
/**
43+
* @param Throwable $ex
44+
* @return array<array-key, mixed>
45+
*/
46+
private function context(Throwable $ex): array
47+
{
48+
if ($ex instanceof ContextProvider) {
49+
return $ex->context();
50+
}
51+
52+
if (method_exists($ex, 'context')) {
53+
$context = $ex->context();
54+
return is_array($context) ? $context : [];
55+
}
56+
57+
return [];
58+
}
4059
}

tests/Unit/Infrastructure/ExceptionReporter/PsrLogExceptionReporterTest.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
namespace CloudCreativity\Modules\Tests\Unit\Infrastructure\ExceptionReporter;
1414

1515
use CloudCreativity\Modules\Contracts\Application\Ports\Driven\ExceptionReporter;
16+
use CloudCreativity\Modules\Contracts\Toolkit\Loggable\ContextProvider;
1617
use CloudCreativity\Modules\Infrastructure\ExceptionReporter\PsrLogExceptionReporter;
1718
use LogicException;
1819
use PHPUnit\Framework\MockObject\MockObject;
@@ -83,4 +84,61 @@ public function testItReportsDefaultMessageIfExceptionHasEmptyMessage(): void
8384

8485
$this->assertInstanceOf(ExceptionReporter::class, $this->reporter);
8586
}
87+
88+
public function testItLogsContextForExceptionThatImplementsContextProvider(): void
89+
{
90+
$exception = new class ('Boom!') extends LogicException implements ContextProvider {
91+
public function context(): array
92+
{
93+
return ['foo' => 'bar', 'exception' => null];
94+
}
95+
};
96+
97+
$expected = [
98+
'foo' => 'bar',
99+
'exception' => $exception,
100+
];
101+
102+
$this->logger
103+
->expects($this->once())
104+
->method('error')
105+
->with(
106+
$exception->getMessage(),
107+
$this->identicalTo($expected),
108+
);
109+
110+
$this->reporter->report($exception);
111+
112+
$this->assertInstanceOf(ExceptionReporter::class, $this->reporter);
113+
}
114+
115+
public function testItLogsContextForExceptionThatHasContextMethod(): void
116+
{
117+
$exception = new class ('Boom!') extends LogicException {
118+
/**
119+
* @return array<string, mixed>
120+
*/
121+
public function context(): array
122+
{
123+
return ['foo' => 'bar', 'exception' => null];
124+
}
125+
};
126+
127+
$expected = [
128+
'foo' => 'bar',
129+
'exception' => $exception,
130+
];
131+
132+
$this->logger
133+
->expects($this->once())
134+
->method('error')
135+
->with(
136+
$exception->getMessage(),
137+
$this->identicalTo($expected),
138+
);
139+
140+
$this->reporter->report($exception);
141+
142+
$this->assertInstanceOf(ExceptionReporter::class, $this->reporter);
143+
}
86144
}

0 commit comments

Comments
 (0)