Skip to content

Fire-and-forget async calls with no error handling #399

@rido-min

Description

@rido-min

Summary

Several locations start async operations without awaiting them or handling their exceptions. If these tasks fail, the exceptions are silently lost.

Locations

Incomplete await pattern

  • Plugins.AspNetCore/Extensions/ApplicationBuilder.Functions.cs:56, 71 — Calls handler(context).ConfigureAwait(false).GetAwaiter() without .GetResult() — the task is started but never observed. The handler's result (including exceptions) is discarded.

Intentional fire-and-forget without error handling

  • Plugins.AspNetCore/AspNetCorePlugin.Stream.cs:51, 66, 188_ = Flush() in Timer callbacks. Exceptions thrown by Flush() are unobserved.

Debounce with unobserved continuations

  • Teams.Common/Extensions/ActionExtensions.cs:17-24, 37-44Task.Delay(...).ContinueWith(...) return value is discarded. Exceptions in the continuation are unobserved.

Unnecessary Task.Run for no-op

  • Teams.Apps/Contexts/Context.cs:143Task.Run(() => { }) used as a no-op default. Should be Task.CompletedTask.

Impact

  • Unobserved task exceptions trigger TaskScheduler.UnobservedTaskException and can crash the process depending on configuration
  • Failures in stream flushing or debounced operations are invisible
  • Unnecessary thread pool work for no-op tasks

Suggested fix

  • For ApplicationBuilder.Functions.cs: properly await the handler or return the task
  • For stream flushing: add a try/catch inside the Flush path or log exceptions from the fire-and-forget
  • For debounce: observe the continuation result or add exception handling
  • Replace Task.Run(() => { }) with Task.CompletedTask

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions