fix(query-orchestrator): don't report a cancelled query as a query error - #11759
fix(query-orchestrator): don't report a cancelled query as a query error#11759paveltiunov wants to merge 2 commits into
Conversation
When the queue cancels a query - orphaned, stalled or explicitly cancelled - the queue item is removed and the driver rejects the execution which is still in flight. `executeQuery` logged that rejection as `Error while querying`, the event which marks a query as failed in query history, so a cancellation that is deliberately kept out of query history leaked back in as an error. Athena makes it visible because its driver rejects with `Query was cancelled` rather than a connection-level failure, but it applies to any driver which propagates a cancel as a rejection. Nothing is waiting for the result at that point, which is why `setResultAndRemoveQuery` fails right afterwards and logs `Orphaned execution result`. Log the rejection under a distinct `Cancelled query execution` event carrying `cancellationError` instead. A timeout is excluded: it cancels a query which is still queued, so it stays an error. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fbg1V8t2pGKB91b386YHKi
|
Claude finished @paveltiunov's task in 3m 14s —— View job Review: sound fix, one blocker — the new event is invisible under the default logger1 high, 1 medium, 2 low. 4 inline comments posted. Full review
SummaryThe diagnosis is right and the fix is in the right place. Findings
On #1 — this is the one worth acting on before merge. What's good
VerificationI read the code and traced the log-event consumers; I did not run the test suite or the linter in this environment. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #11759 +/- ##
===========================================
- Coverage 80.15% 59.95% -20.20%
===========================================
Files 500 240 -260
Lines 105493 19190 -86303
Branches 3851 3887 +36
===========================================
- Hits 84554 11505 -73049
+ Misses 20391 7135 -13256
- Partials 548 550 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Address review on #11759. The default logger routes purely on `error` / `warning`, so an event carrying neither is dropped at the default `info` level: the new `Cancelled query execution` event would have removed the rejection from OSS logs entirely rather than reclassifying it. Set `warning`, which keeps the event at the default level without the `error` field that flags a query as failed downstream. Also note in the comment that the queue lookup runs after the rejection, so a query which genuinely fails as its item is orphaned is reclassified too, log the unhashed query key and the request id from the lookup's own error path like every other event in the class, and tighten the test's poll so a worker which never picks the query up fails on the poll rather than on the log assertions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fbg1V8t2pGKB91b386YHKi
|
Claude finished @paveltiunov's task in 1m 47s —— View job Re-review of
|
| # | Location | Note |
|---|---|---|
| 1 | QueryQueue.ts:1004-1009 |
Still a 6-line comment for one boolean. The load-bearing halves are "a missing queue item means the queue cancelled it" and "the lookup is after the fact, so a concurrent orphan reclassifies a real failure". The history/timeout sentences could go. Raising it once more only because the repo guideline is 3 lines; not worth another round on its own. |
| 2 | QueryQueue.ts:1010 |
Every non-timeout query error now costs an extra getQueryDef round trip when queryCancelled is false — a network call for the CubeStore queue driver. Errors are rare enough that this is fine, but it is a new call on the failure path. |
| 3 | QueryQueue.ts:1032 |
The warning string restates the event name. Harmless; it's what makes the event routable. |
Verification
I read the code and traced the logger routing end to end in this checkout. I did not run the test suite or the linter here — the CubeStore variant of the queue suite needs Docker, and the packages aren't built in this environment. The author reports 147/147 on yarn unit plus clean lint and tsc --noEmit.
CI on
|
| Check | Failure | Why it isn't this PR's |
|---|---|---|
tests (mssql, false) |
ConnectionError: Login failed for user 'sa' — every suite fails to run |
The MSSQL container never accepted a login. No test body executed. Green on master's last run (bb15ec5). |
integration (24.x, firebolt, true) |
Authenticator.authenticateServiceAccount → makeRequest fails in FireboltDriver.initConnection; the dependent "query should fail on timeout" assertion then fails too |
Firebolt's service-account auth endpoint rejected the request. Green on master's last run (bb15ec5). |
Neither is red on the base branch, so there is no fix to port. Re-running the failed jobs once to confirm; a second failure would be treated as real.
Everything the diff can actually affect is green on this head: lint, build, unit (24.x, 3.13), unit-core, integration-cubestore (24.x). Locally, yarn unit in packages/cubejs-query-orchestrator is 147/147 with clean lint and tsc --noEmit.
Generated by Claude Code
Both re-runs passed — the two failures were transient, as expected
One check is still red and it is mine, not the code's: Everything else on Generated by Claude Code |
Check List
Issue Reference this PR resolves
CORE-861 — follow-up to CUB-4099
Description of Changes Made
When the queue cancels a query — orphaned, stalled, or explicitly cancelled — the queue item is removed and the driver rejects the execution that is still in flight.
QueryQueue.executeQuerylogged that rejection asError while querying, which is the event that marks a query as failed in query history. So a cancellation that is deliberately kept out of query history (Removing orphaned queryandOrphaned execution resultare both treated as cancellations) leaked back in as an error:Athena makes it visible because its driver rejects with an explicit message rather than a connection-level failure, but the same applies to any driver that propagates a cancel as a rejection. Nothing is waiting for the result at that point, which is why
setResultAndRemoveQueryfails immediately afterwards and logsOrphaned execution result.The catch now checks whether the queue item is still there and, when it is gone, logs the rejection under a distinct
Cancelled query executionevent carryingcancellationErrorinstead ofError while querying/error— a cancellation is not a failure, and theerrorfield is what flags one downstream. A timeout is excluded: it cancels a query that is still queued, so it stays an error, and the check is skipped for it entirely. A queue lookup failure resolves to "not cancelled", so a queue storage issue can never hide a genuine query error.The existing
Removing orphaned query/Cancelling query manual/Orphaned execution resultevents are unchanged, so nothing downstream loses its cancellation signal.Testing
New unit test in the shared
QueryQueuesuite (runs for both the in-memory and the Cube Store queue driver): a running query is cancelled mid-execution and the suite asserts the queue logsCancelled query executionand notError while querying. It fails against master, which logs["…", "Cancelling query manual", "Error while querying", "Orphaned execution result", "…"].yarn unitinpackages/cubejs-query-orchestrator: 147 passed / 147. Lint andtsc --noEmitclean.🤖 Generated with Claude Code
https://claude.ai/code/session_01Fbg1V8t2pGKB91b386YHKi
Generated by Claude Code