fix: wrap all parameter serialization errors in InputError - #1772
fix: wrap all parameter serialization errors in InputError#1772arthurschreiber wants to merge 4 commits into
Conversation
In the RPC request payload, only errors thrown while generating a parameter's data were wrapped in an `InputError` naming the failing parameter. Errors thrown while generating the parameter's type info or length prefix (e.g. a `RangeError` from writing an out-of-range length) escaped as raw, unattributed errors instead. All three serialization steps now go through the same error wrapping. The downstream behavior is unchanged and remains sound: a payload error aborts the partially written request message by setting the packet status IGNORE bit (MS-TDS s2.2.3.1.2) and surfaces on the request's callback. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fxv5h4UMCGJEpjgCKcAxug
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Reviewed the diff. This is a small, well-targeted fix — feedback below. SummaryThe fix is correct and minimal: moving Correctness
Test coverage
Minor/optional observations (not blocking)
Nice, focused fix with good test coverage and a well-reasoned validation note on the wire-protocol side. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1772 +/- ##
==========================================
+ Coverage 81.02% 81.09% +0.06%
==========================================
Files 92 92
Lines 4948 4966 +18
Branches 938 939 +1
==========================================
+ Hits 4009 4027 +18
Misses 640 640
Partials 299 299 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Apply the same error wrapping to bulk loads: errors thrown while generating a column's metadata previously escaped the row transform without any deliberate handling, and errors thrown while serializing row values surfaced raw and without naming the affected column. Both now surface as an `InputError` naming the column, with the original error as `cause`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fxv5h4UMCGJEpjgCKcAxug
ReviewNice, focused fix — the RPC and bulk-load error paths now attribute failures to the parameter/column that caused them, and the new unit tests do a good job pinning down each of the three serialization steps independently. A few things worth a look: Inconsistency:
|
Restructure the error wrapping so that only the data type's serialization calls sit inside the try/catch blocks. Errors from stream internals (e.g. `Transform#push`) or from the consumer of the payload generator are no longer misattributed to the parameter or column being serialized. The RPC parameter data generator is iterated manually so that it keeps streaming values lazily (relevant for table-valued parameters, which yield many buffers); the bulk load path collects a single column value's buffers (a small, bounded set) before pushing them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fxv5h4UMCGJEpjgCKcAxug
|
Reviewed the changes to A few observations, none blocking: 1. Asymmetric protection around const parameterData = type.generateParameterData(param, this.options)[Symbol.iterator]();
while (true) {
let result;
try {
result = parameterData.next();
} catch (error) { ... }The call parameterDataBuffers = [...c.type.generateParameterData(parameter, this.mainOptions)];In practice every real 2. Double-wrapping for TVP parameters
3. Minor test duplication The Other notes
Nice work on isolating exactly which calls needed the try/catch in the final commit — that's the trickiest part of this kind of change to get right. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 67fcfd9433
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
`generateParameterData` does not have to be implemented as a generator function - a plain function implementation performing synchronous setup before returning its iterator throws at call time, which the narrowed error wrapping no longer covered. Wrap the iterator construction as well, restoring the coverage the original `yield *` form had. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fxv5h4UMCGJEpjgCKcAxug
ReviewOverall this is a solid, well-scoped fix — consistent 1.
|
Problem
Parameter serialization errors are wrapped inconsistently, and in some paths not handled at all:
RPC requests (
RpcRequestPayload.generateParameterData): only errors thrown while generating a parameter's data are wrapped in anInputErrorthat names the failing parameter:Errors thrown while generating the parameter's type info or length prefix — e.g. a
RangeError: The value of "value" is out of rangefrom writing an out-of-range length — escape as raw, unattributed errors with no indication of which parameter caused the failure.Bulk loads (
RowTransform._transform): errors thrown while generating a column's metadata (getColMetaData→generateTypeInfo) escaped the transform with no deliberate handling at all (relying on Node's stream internals to capture a synchronous_transformthrow), and errors thrown while serializing row values surfaced raw, without naming the affected column.Fix
All serialization steps now go through the same
InputErrorwrapping:Input parameter '<name>' could not be validated, original error ascause(unchanged message, now covering all three steps).Column '<name>' could not be serialized, original error ascause, for both column metadata generation and row value serialization.Note one deliberate behavior change: bulk load serialization failures that previously surfaced the raw error on the bulk load's callback (e.g. the
RangeErrorfor an out-of-rangeDECIMALvalue) now surface the wrappingInputError, with the original error available ascause. The existing integration test covering this path (should not throw in _transform function) was updated accordingly.Validation
The downstream recovery paths are unchanged and were validated against the spec: when a request payload errors,
Connection.makeRequestaborts the partially written request message by setting the packet status IGNORE bit together with EOM ([MS-TDS] v20260617 s2.2.3.1.2: "(From client to server) Ignore this event (0x01 MUST also be set)"), so the connection remains usable and the error surfaces on the request's callback; bulk loads destroy the row/packet streams and surface the error on the bulk load's callback as before. This change only affects error typing and attribution, not the wire behavior.New unit tests cover errors thrown from each RPC serialization step and both bulk load paths. Full unit suite (450 tests) and the RPC, parameterised-statement, and bulk load integration suites (206 tests, against SQL Server 2022) pass.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Fxv5h4UMCGJEpjgCKcAxug