Connection robustness improvements (#813)

* Clear heartbeat and queue when disconnected

* Give clearer error in case configure fails due to a lost connection. Used to throw 'Packet does not exist'

* If the queue processing error is due to a lost connection, throw it instead of looping endlessly

* In case we send a disconnection event we don't need to also throw

* Catch heartbeat errors

* Also handle invalid state errors

* Handle socket timeouts

* Log heartbeat failures

* Make linter happy

* Transform stream being a singleton prevented reconnection attempts

* Adapt tests to not using singleton

* Aborting already ends the connection
This commit is contained in:
Henri Bergius
2025-09-04 13:08:05 -04:00
committed by GitHub
parent dcb44d27fe
commit bcdda8b751
11 changed files with 124 additions and 54 deletions
+19 -2
View File
@@ -64,6 +64,11 @@ export class MeshDevice {
this.isConfigured = true;
} else if (status === DeviceStatusEnum.DeviceConfiguring) {
this.isConfigured = false;
} else if (status === DeviceStatusEnum.DeviceDisconnected) {
if (this._heartbeatIntervalId !== undefined) {
clearInterval(this._heartbeatIntervalId);
}
this.complete();
}
});
@@ -770,7 +775,14 @@ export class MeshDevice {
},
});
return this.sendRaw(toBinary(Protobuf.Mesh.ToRadioSchema, toRadio));
return this.sendRaw(toBinary(Protobuf.Mesh.ToRadioSchema, toRadio)).catch(
(e) => {
if (this.deviceStatus === DeviceStatusEnum.DeviceDisconnected) {
throw new Error("Device connection lost");
}
throw e;
},
);
}
/**
@@ -797,7 +809,12 @@ export class MeshDevice {
clearInterval(this._heartbeatIntervalId);
}
this._heartbeatIntervalId = setInterval(() => {
this.heartbeat();
this.heartbeat().catch((err) => {
this.log.error(
Emitter[Emitter.Ping],
`⚠️ Unable to send heartbeat: ${err.message}`,
);
});
}, interval);
}