When a client aborts a request mid-stream, I keep catching TaskCanceledException bubbling out of my controller actions. My current repository pattern looks like this:
public async Task<IActionResult> GetById(int id)
{
// Shared SqlConnection
var result = await _db.QueryFirstOrDefaultAsync<Product>(
"SELECT * FROM Products WHERE Id = @id", new { id });
return Ok(result);
}
The connection opens inside a using block in the repository, yet the async call still throws on cancellation. Should I be passing a CancellationToken all the way down, or is there a Dapper-specific setting I'm overlooking? I don't want to swallow cancellations silently.
A
TaskCanceledExceptionfrom an async Dapper call usually means the database operation was canceled—not necessarily that Dapper failed. In ASP.NET Core, the request may have been canceled because the client disconnected or the server stopped processing it. A database command timeout or cancellation from elsewhere can also be involved.Pass the request cancellation token into Dapper using a
CommandDefinition. Dapper's simpler async overloads generally don't take a cancellation token directly.The action's
CancellationTokenis normally linked toHttpContext.RequestAborted. Passing it through makes the database work stop when the request no longer needs a result. The database provider must support cancellation for this to take effect promptly.Should the controller catch it?
Usually, no. If the request was aborted, there may be no client left to receive an error response. Let cancellation propagate rather than converting it into a 500 response. If you do catch it for cleanup or logging, check whether the request cancellation token was canceled; avoid logging expected request cancellations as application errors.
If the request token was not canceled, investigate the database command timeout and provider behavior. A timeout may surface as a provider-specific exception rather than
TaskCanceledException, so inspect the inner exception and logs before treating every cancellation as the same problem. Also, setting a longer database command timeout is not a substitute for diagnosing a slow query.