Skip to content

Distinguish cancellation from failure to allow different logging strategies #19526

Description

@ascott18

What problem are you trying to solve?
Right now, logs for exceptions thrown due to CancellationToken cancellation are categorized as Microsoft.EntityFrameworkCore.Query[10100]. I want to be able to keep logging all other kinds of query errors, but not ones for intentional cancellations. In my application, I'm passing aspnetcore's HttpContext.RequestedAborted token to my async EF query evaluations. If the client hangs up, there's no reason to keep querying the database working to evaluate what are in some cases quite complex search queries in an intranet application (e.g. if the client changed their search criteria, or just left the page).

We'd like to not pollute our logs with these exceptions that are fully expected. We have an ActionFilter where we handle the exception as far as aspnetcore is concerned, but EF itself still logs the error.

For example:

fail: Microsoft.EntityFrameworkCore.Query[10100]
      An exception occurred while iterating over the results of a query for context type 'My.App.AppDbContext'.
      System.Threading.Tasks.TaskCanceledException: A task was canceled.
         at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
         at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
         at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
         at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)
System.Threading.Tasks.TaskCanceledException: A task was canceled.
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
   at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106
   at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)

Describe the solution you'd like

Create a dedicated log category for OperationCanceledExceptions that are caused by userspace-provided CancellationTokens that I can then setup a regular logging filter against.

Alternatively, just do not log OperationCanceledException at all if the CancellationToken has been triggered, since this is generally always an intentional outcome if the user has passed a CancellationToken to their query evaulations. This would be a much simpler path, but may have unintended consequences.

Activity

  1. ajcvickers commented on Jan 11, 2020

    @ajcvickers
    Contributor

    Note from team discussion: putting this on the backlog to consider generating a different logging event when the exception is "TaskCanceledException".

  2. added this to the Backlog milestone on Jan 11, 2020
  3. changed the title [-]Add a way to suppress/filter logging for TaskCanceledException thrown due to cancellation of user-provided CancellationToken[/-] [+]Add a way to suppress/filter logging of TaskCanceledExceptions thrown by user-triggered cancellation[/+] on Jan 21, 2020
  4. MattJacobi-ESO commented on May 6, 2020

    @MattJacobi-ESO

    I'm having this problem as well. I would like to provide some additional context. Sometimes cancellation can actually generate multiple errors, some of which cannot be identified as being caused by cancellation.

    For example, if you trigger the cancellation token before the database connection is made, you'll actually get two errors logged:

    Error 1

    Microsoft.EntityFrameworkCore.Database.Connection: An error occurred using the connection to database '<mydb>' on server '<myserver>'.
    

    Error 2

    Microsoft.EntityFrameworkCore.Query: An exception occurred while iterating over the results of a query for context type '<mydbcontext>'.
    System.Threading.Tasks.TaskCanceledException: A task was canceled.
    <callstack>
    

    Error 2 is noise -- and I'd love to be able to suppress it -- but it is at least possible to conclude that the error is likely due to a cancellation token. You can use the presence of "TaskCanceledException" to filter it out.

    However, if you look at Error 1, there is no indication that this was actually caused by cancellation. This can lead to unnecessary investigation. And there is also no way to filter it out as "noise".

  5. 4lexKislitsyn commented on May 7, 2021

    @4lexKislitsyn

    You can use the presence of "TaskCanceledException" to filter it out

    OperationCanceledException can be filter out too. It can be thrown from ThrowIfCancellationRequested method, e.g. here

  6. plachor commented on May 14, 2021

    @plachor

    Similar in my case, when request is aborted I see 2 log entries with Error severity level:

    "MessageTemplate: "Failed executing DbCommand ({elapsed}ms) [Parameters=[{parameters}], CommandType='{commandType}', CommandTimeout='{commandTimeout}']{newLine}{commandText}",
    "SourceContext": "Microsoft.EntityFrameworkCore.Database.Command"
    

    and

    "MessageTemplate": "An exception occurred while iterating over the results of a query for context type '{contextType}'.{newline}{error}",
    "SourceContext": "Microsoft.EntityFrameworkCore.Query"
    

    Second one contains information regarding cause which was OperationCanceledException, but first one has no such indicator. Still I'm far away from parsing some string property to check if it is operation cancelled - I would need than to recheck this with my request cancellation token to be 100% sure this something I can suppress or not.

    Best solution for my scenario would be a setting on DbContext allowing to lower severity of all logs from Error to Debug that are outcome of a cancellation token being cancelled but only for the one that was passed to the root invocation.

  7. KrzysztofBranicki commented on May 15, 2021

    @KrzysztofBranicki

    @ajcvickers Hi, is there any timeline where we can expect a fix for this bug? The way it is working currently basically renders all APIs that use CancellationToken useless. Unless someone doesn't mind polluting his logs with flood of errors that aren't really errors (highly unlikely for any production application). My scenario is the same as others in this issue - passing ASP.CORE HTTP request related CancellationToken to handle scenarios like browser closed, F5, frontend auto complete searches etc.

  8. jxlarrea commented on May 19, 2021

    @jxlarrea

    Same here. My ASP.NET Core application is unnecessarily logging thousands of TaskCanceledException errors every day due to CancellationToken being passed to EF Core queries. It is insane that this hasn't been resolved yet.

  9. adomass commented on May 19, 2021

    @adomass

    I think this should have a label urgent-fix not consider-for-next-release. Logging system is spammed with those errors and we are waiting for this issue to be solved for a year.

  10. michael-jenkinson commented on Jun 2, 2021

    @michael-jenkinson

    Agreed, it is very annoying, and drowning out real errors.

  11. KrzysztofBranicki commented on Jul 19, 2021

    @KrzysztofBranicki

    @ajcvickers can we expect this to be fixed in 6.0?

  12. ajcvickers commented on Jul 19, 2021

    @ajcvickers
    Contributor

    @KrzysztofBranicki No, this is in the backlog milestone, which means it is not planned to be fixed for 6.0. See release-planning for information about how we plan which features go into a release. While this is an important, there are currently 53 feature requests that have more votes than this one, so it didn't make it into 6.0.

  13. 25 remaining items

  14. brockallen commented on Jan 24, 2023

    @brockallen

    Sorry to rekindle this thread, but is it documented or can you provide any insight into when an OperationCanceledException is thrown vs when a TaskCanceledException is thrown? We're trying to tune the filter and don't want to use OperationCanceledException is that's too broad and suppresses other meaningful exceptions/conditions. TIA!

    // @josephdecock

  15. roji commented on Jan 25, 2023

    @roji
    Member

    EF itself considers any OperationCanceledException as meaning that the operation was canceled, e.g. for the purposes of logging an error vs. a cancellation; I'd suggest you do the same. In the general case you shouldn't be catching TaskCanceledException, but rather OperationCanceledException.

  16. brockallen commented on Jan 25, 2023

    @brockallen

    Thank you @roji!

  17. sommmen commented on Feb 13, 2023

    @sommmen
  18. ascott18 commented on Feb 13, 2023

    @ascott18
    Author
  19. roji commented on Mar 22, 2023

    @roji
  20. sayowayah commented on Apr 12, 2023

    @sayowayah

    Just wondering if this is still partially an issue? I'm still seeing some Microsoft.EntityFrameworkCore.Database.Connection.ConnectionError error logs when a task is cancelled. My OperationCanceledException handler is properly triggering for the same request, so it seems the new OperationCanceledException is throwing, but EF still logs that Database.Connection.ConnectionError somewhere along the way. It seems that @roji had some back and forth with someone here about the same/similar issue, but I don't see a resolution.

    I was thinking about configuring EF to drop RelationalEventId.ConnectionError logs to warning, but that doesn't seem great if there's actually some other non-cancellation-related error.

    More details in case my specific settings are related:

    • Microsoft.EntityFrameworkCore.SqlServer 7.0.3
    • Azure SQL Managed Instance
    • Details for this particular query
      • Wrapped in a TransactionScope with IsolationLevel.ReadUncommitted
      • Database.SetCommandTimeout(60)
      • AsNoTracking()
  21. roji commented on Apr 12, 2023

    @roji
    Member

    @sayowayah as far as I know the issue is solved... If you're seeing otherwise, we're going to need to see some sort of runnable repro to investigate. The SO issue linked to above was unable to do so.

  22. ravindUwU commented on Feb 27, 2025

    @ravindUwU
  23. roji commented on Feb 28, 2025

    @roji
  24. ravindUwU commented on Mar 1, 2025

    @ravindUwU
  25. added theissue type on Jun 15, 2025
  26. 0xced commented on Oct 16, 2025

    @0xced
    Contributor

    Providers can create their own IExecutionDetector and add specific logic for identifying cancellation exceptions as necessary.

    You meant IExceptionDetector 😉.

    For people skimming through issues related to dotnet/SqlClient#26, writing a custom IExceptionDetector will only affect EF Core logs. This will not turn SqlException into a proper OperationCanceledException. For this, a custom IExecutionStrategy would be needed. See https://github.com/0xced/efmssql for more information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions