self-heal protocol handler registration on re-init

Core::new() registers default protocol handlers after starting networking,
but swallows any failure (error is only logged). If the initial registration
fails — e.g. on a host where start_networking hasn't fully set up the event
loop command sender by the time register_default_protocol_handlers runs —
the registry is left empty. A subsequent call to Core::init_networking()
would see `services.networking().is_some()` and skip re-registration,
permanently leaving protocols unregistered for the life of the process.

sd-server calls init_networking() right after Core::new(), so it's the
client most exposed to this. Symptom: pairing over the web UI returns
"Pairing protocol not registered" while the same library works fine
from Tauri and mobile.

Fix: init_networking now queries the registry directly for the pairing
handler and re-registers the default set if it's missing, independent of
whether networking is already initialized.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
James Pine
2026-04-17 18:25:48 -07:00
parent 8fde30a187
commit 452fbf46d7

View File

@@ -520,10 +520,27 @@ impl Core {
// Register protocols and set up event bridge
if let Some(networking_service) = self.services.networking() {
// Register default protocol handlers only if networking was just initialized
// (if networking was already initialized during Core::new(), protocols are already registered)
if !already_initialized {
logger.info("Registering protocol handlers...").await;
// Core::new() attempts to register default protocols after starting
// networking, but swallows errors (only logs them). That means
// `already_initialized` does NOT imply protocols are registered —
// e.g. if the event loop's command sender wasn't ready when Core::new()
// tried to build the pairing handler, registration silently failed.
// Check the registry directly and re-register if missing.
let pairing_registered = networking_service
.protocol_registry()
.read()
.await
.get_handler("pairing")
.is_some();
if !already_initialized || !pairing_registered {
if already_initialized && !pairing_registered {
logger
.warn("Networking was initialized but protocol handlers are missing; re-registering")
.await;
} else {
logger.info("Registering protocol handlers...").await;
}
self.register_default_protocols(&networking_service).await?;
} else {
logger