< Summary

Information
Class: Pomodoro.Web.Services.SafeTaskRunner
Assembly: Pomodoro.Web
File(s): /home/runner/work/Pomodoro/Pomodoro/src/Pomodoro.Web/Services/SafeTaskRunner.cs
Line coverage
100%
Covered lines: 25
Uncovered lines: 0
Coverable lines: 25
Total lines: 66
Line coverage: 100%
Branch coverage
100%
Covered branches: 2
Total branches: 2
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
RunAndForget(...)100%11100%
ExecuteSafelyAsync()100%11100%
RunAndForget(...)100%11100%
ExecuteSafelyAsync()100%22100%

File(s)

/home/runner/work/Pomodoro/Pomodoro/src/Pomodoro.Web/Services/SafeTaskRunner.cs

#LineLine coverage
 1using Microsoft.Extensions.Logging;
 2
 3namespace Pomodoro.Web.Services;
 4
 5/// <summary>
 6/// Provides safe fire-and-forget task execution with exception logging.
 7/// Use this instead of discard pattern to ensure exceptions are logged.
 8/// </summary>
 9public static class SafeTaskRunner
 10{
 11    /// <summary>
 12    /// Runs a task asynchronously without awaiting, logging any exceptions.
 13    /// </summary>
 14    /// <param name="task">The async task to execute.</param>
 15    /// <param name="logger">The logger to use for exception logging.</param>
 16    /// <param name="operationName">A descriptive name for the operation for logging purposes.</param>
 17    public static void RunAndForget(
 18        Func<Task> task,
 19        ILogger logger,
 20        string operationName = Constants.SafeTaskOperations.UnknownOperation)
 48521    {
 48522        _ = ExecuteSafelyAsync(task, logger, operationName);
 48523    }
 24
 25    private static async Task ExecuteSafelyAsync(Func<Task> task, ILogger logger, string operationName)
 48526    {
 27        try
 48528        {
 48529            await task().ConfigureAwait(false);
 47430        }
 731        catch (Exception ex)
 732        {
 733            logger.LogError(ex, Constants.SafeTaskOperations.ErrorInOperationLogFormat, operationName);
 734        }
 48135    }
 36
 37    /// <summary>
 38    /// Runs a task asynchronously without awaiting, logging any exceptions.
 39    /// </summary>
 40    /// <typeparam name="T">The type of the task result.</typeparam>
 41    /// <param name="task">The async task to execute.</param>
 42    /// <param name="logger">The logger to use for exception logging.</param>
 43    /// <param name="operationName">A descriptive name for the operation for logging purposes.</param>
 44    /// <param name="onSuccess">Optional callback when the task succeeds.</param>
 45    public static void RunAndForget<T>(
 46        Func<Task<T>> task,
 47        ILogger logger,
 48        string operationName = Constants.SafeTaskOperations.UnknownOperation,
 49        Action<T>? onSuccess = null)
 450    {
 451        _ = ExecuteSafelyAsync(task, logger, operationName, onSuccess);
 452    }
 53
 54    private static async Task ExecuteSafelyAsync<T>(Func<Task<T>> task, ILogger logger, string operationName, Action<T>?
 455    {
 56        try
 457        {
 458            var result = await task().ConfigureAwait(false);
 259            onSuccess?.Invoke(result);
 260        }
 261        catch (Exception ex)
 262        {
 263            logger.LogError(ex, Constants.SafeTaskOperations.ErrorInOperationLogFormat, operationName);
 264        }
 465    }
 66}