Preserve the original exception when SqlDataReader teardown also times out
- Dominant language
- C#
- Stars
- 989
- Forks
- 340
- Avg merge
- 4d 19h
- Merged PRs (30d)
- 72
Description
### Describe the bug
When a per-row transform throws while processing a result set, reader teardown can subsequently time out while draining the remaining rows. The teardown exception, ending in `Win32Exception (258): Unknown error 258`, replaces the original transform exception entirely. The caller cannot determine why row processing failed.
This variant was confirmed in the [Cause B analysis on #1530](https://github.com/dotnet/SqlClient/issues/1530#issuecomment-5404606795). The [follow-up comment](https://github.com/dotnet/SqlClient/issues/1530#issuecomment-5528129710) proposes surfacing both exceptions through an `AggregateException`.
```
Exception message: Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Inner exception: System.ComponentModel.Win32Exception (258): Unknown error 258
Stack trace: The teardown timeout replaces the exception thrown by the per-row transform.
```
### To reproduce
1. Execute a query that returns enough rows that draining them exceeds a short `CommandTimeout`.
2. Throw an exception from a per-row transform before the result set is consumed.
3. Close the reader during exception cleanup.
4. Observe that the close-time timeout replaces the transform exception.
The linked analysis reports a deterministic reproduction.
### Expected behavior
Preserve and surface both the original row-processing exception and the reader teardown exception, for example through an `AggregateException`.
### Further technical details
Microsoft.Data.SqlClient version: Reproduced with the stacks covered by the linked Cause B analysis
.NET target: Sync and async reader teardown paths are relevant
SQL Server version: Reproduced with SQL Server in Docker
Operating system: Linux
**Additional context**
This issue tracks exception preservation separately from improving the opaque Cause B timeout message. Parent issue: #1530.
Contributor guide
Research direction
Start with the linked Cause B analysis on #1530 and reproduce the failure using SQL Server in Docker with a short command timeout. Inspect the sync and async reader teardown paths; done means both the per-row transform exception and any teardown exception are surfaced together rather than the teardown exception replacing the original.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100