• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

net-daemon / netdaemon / 29074187479

10 Jul 2026 06:34AM UTC coverage: 83.642% (+0.3%) from 83.301%
29074187479

Pull #1389

github

web-flow
Merge 8f16545ac into b913b8f1e
Pull Request #1389: [codex] Improve high-event hot paths

901 of 1217 branches covered (74.03%)

Branch coverage included in aggregate %.

84 of 85 new or added lines in 3 files covered. (98.82%)

3 existing lines in 1 file now uncovered.

3440 of 3973 relevant lines covered (86.58%)

982.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.89
/src/Client/NetDaemon.HassClient/Internal/Helpers/ResultMessageHandler.cs
1
using System.Collections.Concurrent;
2

3
namespace NetDaemon.Client.Internal.Helpers;
4

5
/// <summary>
6
/// Handles the result of a 'fire and forget` Message tp Home Assistant
7
/// We mainly make sure that any Errors from HA or technical exceptions will get logged correctly
8
/// We also track the tasks so we can await for all pending tasks to finish
9
/// </summary>
10
internal class ResultMessageHandler(ILogger logger) : IAsyncDisposable
50✔
11
{
12
    private readonly ConcurrentDictionary<Task, object?> _backgroundTasks = new();
50✔
13

14
    public void HandleResult(Task<HassMessage> returnMessageTask, CommandMessage originalCommand)
15
    {
16
        var withErrorHandling = HandleResultError(returnMessageTask, originalCommand);
23✔
17

18
        // Save the task in the dictionary and remove it when it is done
19
        // this allows us to wait for all pending background tasks to finish
20
        _backgroundTasks.TryAdd(withErrorHandling, null);
23✔
21
        withErrorHandling.ContinueWith(_ => _backgroundTasks.TryRemove(withErrorHandling, out var _));
46✔
22
    }
23✔
23

24
    private async Task HandleResultError(Task<HassMessage> returnMessageTask, CommandMessage originalCommand)
25
    {
26
        try
27
        {
28
            var result = await returnMessageTask.ConfigureAwait(false);
23✔
29
            if (!result.Success ?? false)
18!
30
            {
31
                logger.LogError("Failed command ({CommandType}) error: {ErrorResult}.  Sent command is {CommandMessage}",
1✔
32
                    originalCommand.Type, result.Error, originalCommand.GetJsonString());
1✔
33
            }
34
        }
18✔
35
        catch (TimeoutException)
1✔
36
        {
37
            logger.LogWarning("Command ({CommandType}) did not get response in timely fashion.  Sent command is {CommandMessage}",
1✔
38
                originalCommand.Type, originalCommand.GetJsonString());
1✔
39
        }
1✔
40
        catch (OperationCanceledException)
3✔
41
        {
42
            // Expected during connection shutdown or caller cancellation.
43
        }
3✔
44
        catch (Exception e)
1✔
45
        {
46
            logger.LogError(e, "Exception waiting for result message.  Sent command is {CommandMessage}", originalCommand.GetJsonString());
1✔
47
        }
1✔
48
    }
23✔
49

50
    public async Task WaitPendingBackgroundTasksAsync()
51
    {
52
        if (!_backgroundTasks.IsEmpty)
54✔
53
        {
54
            await Task.WhenAll(_backgroundTasks.Keys).ConfigureAwait(false);
5✔
55
        }
56
    }
54✔
57

58
    public async ValueTask DisposeAsync()
59
    {
60
        try
61
        {
62
            await WaitPendingBackgroundTasksAsync().WaitAsync(TimeSpan.FromSeconds(5)).ConfigureAwait(false);
49✔
63
        }
49✔
UNCOV
64
        catch (TimeoutException e)
×
65
        {
UNCOV
66
            logger.LogError(e, "One or requests are still pending while closing connection to Home Assistant");
×
UNCOV
67
        }
×
68
    }
49✔
69
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc