Skip to content

Commit 015f874

Browse files
committed
Immediately ingest unhandled exceptions
1 parent e5b3d92 commit 015f874

File tree

5 files changed

+46
-43
lines changed

5 files changed

+46
-43
lines changed

src/Concerns/CapturesState.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,12 @@ public function report(Throwable $e, ?bool $handled = null): void
171171
}
172172

173173
try {
174-
if ($e instanceof FatalError) {
175-
if ($this->sampling) {
176-
$this->ingest->writeNow($this->sensor->fatalError($e));
177-
}
174+
$record = $this->sensor->exception($e, $handled);
175+
176+
if ($this->sampling && ($e instanceof FatalError || ! $record['handled'])) {
177+
$this->ingest->write($record);
178178
} else {
179-
$this->ingest->write($this->sensor->exception($e, $handled));
179+
$this->ingest->write($record);
180180
}
181181
} catch (Throwable $e) {
182182
Nightwatch::unrecoverableExceptionOccurred($e);

src/SensorManager.php

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,13 @@
4242
use Laravel\Nightwatch\Sensors\UserSensor;
4343
use Laravel\Nightwatch\State\CommandState;
4444
use Laravel\Nightwatch\State\RequestState;
45-
use Laravel\Nightwatch\Types\Str;
4645
use Monolog\LogRecord;
4746
use Psr\Http\Message\RequestInterface;
4847
use Psr\Http\Message\ResponseInterface;
4948
use Symfony\Component\Console\Input\InputInterface;
5049
use Symfony\Component\HttpFoundation\Response;
5150
use Throwable;
5251

53-
use function hash;
54-
5552
/**
5653
* @internal
5754
*/
@@ -252,38 +249,6 @@ public function exception(Throwable $e, ?bool $handled): array
252249
return $sensor($e, $handled);
253250
}
254251

255-
/**
256-
* @return array<mixed>
257-
*/
258-
public function fatalError(Throwable $e): array
259-
{
260-
$file = $this->location->normalizeFile($e->getFile());
261-
262-
return [
263-
'v' => 3,
264-
't' => 'exception',
265-
'timestamp' => $this->clock->microtime(),
266-
'deploy' => $this->executionState->deploy,
267-
'server' => $this->executionState->server,
268-
'_group' => hash('xxh128', $e::class.','.$e->getCode().','.$file.','.$e->getLine()),
269-
'trace_id' => $this->executionState->trace,
270-
'execution_source' => $this->executionState->source,
271-
'execution_id' => '',
272-
'execution_preview' => $this->executionState->executionPreview,
273-
'execution_stage' => $this->executionState->stage,
274-
'user' => $this->executionState->user->resolvedUserId(),
275-
'class' => $e::class,
276-
'file' => Str::tinyText($file),
277-
'line' => $e->getLine(),
278-
'message' => Str::text($e->getMessage()),
279-
'code' => (string) $e->getCode(),
280-
'trace' => '',
281-
'handled' => false,
282-
'php_version' => $this->executionState->phpVersion,
283-
'laravel_version' => $this->executionState->laravelVersion,
284-
];
285-
}
286-
287252
/**
288253
* @return array<mixed>
289254
*/

src/Sensors/ExceptionSensor.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Spatie\LaravelIgnition\Exceptions\ViewException as IgnitionViewException;
1414
use SplFileObject;
1515
use stdClass;
16+
use Symfony\Component\ErrorHandler\Error\FatalError;
1617
use Throwable;
1718

1819
use function array_is_list;
@@ -35,6 +36,8 @@
3536
*/
3637
final class ExceptionSensor
3738
{
39+
private const int VERSION = 3;
40+
3841
/**
3942
* @var array<string, SplFileObject|null>
4043
*/
@@ -56,6 +59,10 @@ public function __construct(
5659
*/
5760
public function __invoke(Throwable $e, ?bool $handled): array
5861
{
62+
if ($e instanceof FatalError) {
63+
return $this->fatalError($e);
64+
}
65+
5966
$nowMicrotime = $this->clock->microtime();
6067
[$file, $line] = $this->location->forException($e);
6168
$normalizedException = match ($e->getPrevious()) {
@@ -76,7 +83,7 @@ public function __invoke(Throwable $e, ?bool $handled): array
7683
$this->executionState->exceptions++;
7784

7885
return [
79-
'v' => 3,
86+
'v' => self::VERSION,
8087
't' => 'exception',
8188
'timestamp' => $nowMicrotime,
8289
'deploy' => $this->executionState->deploy,
@@ -100,6 +107,35 @@ public function __invoke(Throwable $e, ?bool $handled): array
100107
];
101108
}
102109

110+
private function fatalError(FatalError $e)
111+
{
112+
$file = $this->location->normalizeFile($e->getFile());
113+
114+
return [
115+
'v' => self::VERSION,
116+
't' => 'exception',
117+
'timestamp' => $this->clock->microtime(),
118+
'deploy' => $this->executionState->deploy,
119+
'server' => $this->executionState->server,
120+
'_group' => hash('xxh128', $e::class.','.$e->getCode().','.$file.','.$e->getLine()),
121+
'trace_id' => $this->executionState->trace,
122+
'execution_source' => $this->executionState->source,
123+
'execution_id' => '',
124+
'execution_preview' => $this->executionState->executionPreview,
125+
'execution_stage' => $this->executionState->stage,
126+
'user' => $this->executionState->user->resolvedUserId(),
127+
'class' => $e::class,
128+
'file' => Str::tinyText($file),
129+
'line' => $e->getLine(),
130+
'message' => Str::text($e->getMessage()),
131+
'code' => (string) $e->getCode(),
132+
'trace' => '',
133+
'handled' => false,
134+
'php_version' => $this->executionState->phpVersion,
135+
'laravel_version' => $this->executionState->laravelVersion,
136+
];
137+
}
138+
103139
private function wasManuallyReported(Throwable $e): bool
104140
{
105141
foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, limit: 20) as $frame) {

tests/Unit/Hooks/GuzzleMiddlewareTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ public function test_it_gracefully_handles_exceptions_in_the_before_middleware()
1717
$this->core->sensor->exceptionSensor = function ($e) use (&$exceptions): array {
1818
$exceptions[] = $e;
1919

20-
return [];
20+
return [
21+
'handled' => true,
22+
];
2123
};
2224
$thrownInMicrotimeResolver = false;
2325
$this->core->clock->microtimeResolver = function () use (&$thrownInMicrotimeResolver): float {

tests/Unit/SamplingTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public function test_it_samples_on_exception(): void
224224
{
225225
$ingest = $this->fakeIngest();
226226
$this->core->config['sampling']['requests'] = 0;
227-
$this->core->sensor->exceptionSensor = fn () => [];
227+
$this->core->sensor->exceptionSensor = fn () => ['handled' => false];
228228
$exception = new RuntimeException('Whoops!');
229229
Route::get('/users', fn () => throw $exception);
230230

0 commit comments

Comments
 (0)