dotnet / dotnet/SqlClient

Preserve the original exception when SqlDataReader teardown also times out

Open
#4,638 0 comments 0 reactions 0 assignees View on GitHub
:bug: Bug! Area\Managed SNI
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.