CNA-BUG-161: A handler that throws during HttpNotificationChannel::DispatchPendingNotificationsEXT discards every remaining notification of that batch

CNA snapshot 009d40f5  ·  Known Issues › Current bugs  ·  source links pinned to 009d40f5

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

DispatchPendingNotificationsEXT moves the whole queue into a local vector before raising; an exception from a HttpNotificationReceived handler propagates and destroys the notifications not yet raised.

Identifier
CNA-BUG-161
Category
Bug
Subsystem
Networking & gamer services
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Low (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
Microsoft::Phone::Notification::HttpNotificationChannel::DispatchPendingNotificationsEXT() and HttpNotificationReceived

Expected behaviour

The method is documented as “Raises the events of every notification that has arrived.” A notification that arrived but had not been raised when an earlier handler threw should not disappear: a later call should still raise it, or the method should document that a throwing handler loses the batch.

Actual behaviour at TARGET

The method swaps pending_ into a local vector under mutex_, releases the lock and raises HttpNotificationReceived once per body. Sharp Runtime's EventHandler::Raise invokes handlers without catching, so the first exception leaves the loop and the local vector, holding every body after the throwing one, is destroyed. The next dispatch sees only notifications that arrived after the swap.

Source locations

Evidence

Checked by reading HttpNotificationChannel.cpp at 009d40f5 and System::EventHandler::Raise in sharp-runtime next @ 41b918c9 (iterates a snapshot, no catch; not pinned by TARGET). Not executed. That the other handlers of the throwing notification are skipped is ordinary multicast-delegate behaviour and not part of this entry.

Focused reproduction

No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.

Current tests

NothingIsRaisedUntilTheGameAsksForIt and WhatAServicePostsArrivesAsANotification use handlers that do not throw.

Regression test

Queue three notifications, subscribe a handler that throws on the first, catch the exception around the dispatch, dispatch again, and require the other two to be raised.

Blast radius

Ports whose notification handlers can throw; when only one notification is pending per dispatch nothing further is lost.

Workaround

Catch exceptions inside HttpNotificationReceived handlers.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

Maintainer workflow
Thread and callback map
Known issues
Bug index