Skip to content

fix(sentry): carry the Throwable in swallowed-exception error logs across base - #137

Merged
escapeboy merged 1 commit into
developfrom
fix/base-error-logs-carry-throwable
Aug 4, 2026
Merged

fix(sentry): carry the Throwable in swallowed-exception error logs across base#137
escapeboy merged 1 commit into
developfrom
fix/base-error-logs-carry-throwable

Conversation

@escapeboy

Copy link
Copy Markdown
Owner

Completes the instrumentation sweep behind #824 / #847 / #1035, which arrived at Sentry as bare messages — no exception class, no stacktrace, no context.

sentry-laravel promotes a context['exception'] that is a Throwable to captureException(); anything else becomes captureMessage():

// vendor/sentry/sentry-laravel/src/Sentry/Laravel/SentryHandler.php:164
$exception = $record['context']['exception'] ?? null;
$isException ? $this->hub->captureException($exception) : $this->hub->captureMessage(...);

Scope: 77 sites, 61 files

All of them catch-and-swallow paths in FleetQ's own logic — pipeline, workflow, crew, skill, project, chatbot, approval, listeners, console commands, controllers. Where the log is the only thing Sentry ever sees, it now carries the Throwable.

Deliberately left alone

34 sites where the failure is a third party, not a FleetQ defect. A stacktrace-carrying issue there is pure noise, which is the opposite of the goal:

Domain/Signal/Connectors (24) · Domain/Outbound/Connectors · Domain/Tool/Services (MCP clients) · Infrastructure/Bridge · Telegram / Webhook / Integration delivery actions · the Helicone pricing fetch · the OpenAI embedding call.

Sites that rethrow are also untouched — the framework handler already captures those, so adding the key would duplicate the event. Same reasoning as base BaseStageJob, which keeps its SentryEventCapturer call separate from the log.

Correctness of a 77-site mechanical edit

The first pass used a line-window heuristic to find the enclosing catch, which bound $e in three failed(\Throwable $exception) methods where the catch above had already closed scope — phpstan caught them as Undefined variable: $e (Crew Execute/Validate jobs, SkillImprovementIterationJob). Fixed.

Because phpstan only catches the case where the variable does not exist at all, every one of the 77 insertions was then verified programmatically to bind the variable of its own enclosing catch (...) or failed(Throwable $x) parameter. Zero mismatches remain.

Verification

  • Full base suite: 4856 passed, 15 skipped, 0 failures
  • phpstan: 0 new errors; the 14 that remain are pre-existing and confirmed to be in files this PR does not touch (optional Webklex\PHPIMAP package + unrelated Mcp property access)
  • pint clean

…ross base

Completes the instrumentation sweep. sentry-laravel promotes a
`context['exception']` that is a Throwable to captureException() (class +
stacktrace + grouping); anything else arrives as a bare message that cannot be
diagnosed — the defect behind #824/#847/#1035.

77 sites in 61 files, all of them catch-and-swallow paths in FleetQ's own
logic: pipeline, workflow, crew, skill, project, chatbot, approval, listeners,
console commands, controllers.

DELIBERATELY LEFT ALONE — 34 sites where the failure is a third party, not a
FleetQ defect, and a stacktrace-carrying issue would be pure noise:
Signal/Connectors, Outbound/Connectors, Tool/Services (MCP clients),
Infrastructure/Bridge, Telegram/Webhook/Integration delivery actions, plus the
Helicone pricing fetch and the OpenAI embedding call.

Also left: sites that rethrow (the framework handler already captures those —
adding the key would duplicate the event).

Every insertion was verified to bind the variable of its own enclosing catch or
`failed(Throwable $exception)` parameter; three initial mismatches (Crew
Execute/Validate jobs, SkillImprovementIterationJob) are fixed.

Full base suite: 4856 passed. phpstan: no new errors.
@escapeboy
escapeboy merged commit 1b49c1f into develop Aug 4, 2026
3 checks passed
@escapeboy
escapeboy deleted the fix/base-error-logs-carry-throwable branch August 4, 2026 07:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant