-
Notifications
You must be signed in to change notification settings - Fork 314
Description
When using a cancellation token to cancel an SqlClient async operation, an SqlException is thrown rather than TaskCanceledException. This seems like problematic behavior, here's some analysis.
On the problematic side, standard async APIs generally throw TaskCanceledException, and SqlClient is doing something different and therefore unexpected. Also, as a result, canceled SqlClient tasks don't have status Canceled, they're Faulted instead. This makes differentiating cancellations from real exceptions more difficult, and the problem is compounded if the SqlClient call is just part of a larger async operation (which again, will be faulted instead of canceled unless some manual specific handling is involved).
The argument for the current behavior seems to be that all of SqlClient's server and network errors are raised as SqlException, making it easy to catch all database errors under a single exception type. On the other hand, it seems that cancellation isn't really an error condition as it's been requested by the user and is expected to occur. The TaskCanceledException is simply a mechanism for conveying the cancellation up the stack.
For the record, this was originally reported by @mikkeljohnsen for Npgsql in npgsql/npgsql#1146. Whatever is decided here for SqlClient will also be adopted for Npgsql (which currently behaves like SqlClient in this respect).