Repository navigation
fix: prints, errors and results after a failed statement in a batch were lost - #475
Conversation
…ere lost A statement failing part way through a batch (raiserror severity 11-16, a failed insert, ...) does not end the batch: SQL Server runs the statements after it. The driver stopped at the first error, so every later print, error, result set and proc output param was dropped, and 'done' never fired. - C++: after a statement error, look ahead with SQLMoreResults. SQL_NO_DATA means the batch really ended with the error (one callback, more = false, as before). Otherwise the result it moved to is handed to the next try_read_next_result. Cancel, timeout, broken connection and statement state errors still end it. - Bound params are kept from bind time, so proc output params and the return code arrive even when an earlier statement in the proc failed. - JS: an error from the next result is reported and the query carries on when more results follow. Callback / event 'more' is true until the batch ends; the proc callback now passes 'more' with an error. A promise rejects with the last error, which now always carries the collected results in err._results. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…BC first-result case - reader.js: info messages in the same diagnostics as an error that ends the batch were dropped (e.g. a print just before a throw inside a proc with nocount on). They are now routed as info as well as the errors being returned. - batch-errors tests: the proc test now produces a result before its raiserror, so it covers continuing after an error on every platform. When the first result of a batch is itself the error, SQLExecDirect fails and the unixODBC driver manager (linux / macOS) answers SQLMoreResults with SQL_NO_DATA without asking the driver, so the batch ends there; on windows it carries on. A new test pins each platform's behaviour, and another checks the print-with-final-error case. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Linux CI found a platform difference, which I've now reproduced locally on WSL Ubuntu 22.04 with ODBC Driver 18. When the first result of a batch is itself the error, This matters for procedures with Follow-up commit 217a7f3:
Local results:
|
A paused query holds the connection. Rather than queue new work behind it
indefinitely, a query submitted while another is paused is refused at once:
its callback (or 'error') gets an error with sqlstate HY010 (function sequence
error), then 'done' and 'free', and no 'submitted'. beginTransaction, commit,
rollback and prepare get the error in their callback. Work queued before the
pause still waits its turn.
Once a cancel of a paused query is accepted, the query no longer holds the
connection, so work submitted from the cancel callback queues behind it.
Corpus: queue/paused-then-{submit,cancel-queued-before,resume-queued-before};
the submit and resume cases are agreed.
The Linux CI runs showed 4 error scenarios that differ from Windows: a batch
whose first statement fails at execute loses the rest of the batch on Linux
(more=false, no done). The base commit does the same, so it is older than
this branch (5.6.0's #475 look-ahead). Pinned as .linux.txt transcripts with
status known-bug, captured on WSL Fedora, and described in HANDOVER.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Problem
A statement failing part way through a batch (
raiserrorseverity 11–16, a failed insert, a failing step in a proc) doesn't end the batch: SQL Server runs the statements after it. The driver stopped at the first error, so:donenever firedBefore, the driver delivered
info p1anderror e1, then stopped. Now it deliversinfo p1,error e1,info p2,error e2,info p3,meta,rowanddone, in both polling and non-polling mode.Fix
C++ (
odbc_statement_legacy.cpp)SQLMoreResults.SQL_NO_DATAmeans the batch really ended with the error, so behaviour is unchanged: one callback withmore = false.try_read_next_result.HYT00), a broken connection (08xxx) and statement state errors (HY010,HY007,24000) still end the query.SQLMoreResultserror path no longer reads that result's columns, which is what fixed ODBC errors not bubbling up when PRINT + THROW are used. #396. It now just moves on.JS
reader.js: an error from the next result is reported, and the query carries on when more results follow. Themoreflag is true until the batch ends, for callbacks and forerrorevents.procedure-bound.js: the proc callback now passesmorealong with an error.query-aggregator.js: the rejected error (the last one) always carrieserr._results: every error, info message, result set and output param.Behaviour change (worth a changelog line)
more = false.doneis still not raised for a batch that ends on an error, the same as before. That's left for a separate change.Tests
New
test/batch-errors.test.js(11 tests):moresequenceraiserrorand still returns its output and return codethrow, a conversion error, several compile errors, and a query timeoutLocal (Windows, ODBC 18, SQL Server 2022): full suite 821 passing, 1 pending. Lint is clean.
🤖 Generated with Claude Code