From a70f9d21705c5d94ad7111afd207e122990ea5d8 Mon Sep 17 00:00:00 2001 From: JovannMC Date: Thu, 5 Dec 2024 15:30:59 +0300 Subject: [PATCH] Handle COM reconnection & prevent IMU error spam --- src/languages/en.json | 8 ++++++-- src/main.ts | 28 ++++++++++++++++++++++++++++ src/static/js/index.ts | 8 ++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/languages/en.json b/src/languages/en.json index e76f4c8..aaea101 100644 --- a/src/languages/en.json +++ b/src/languages/en.json @@ -284,13 +284,17 @@ "title": "No COM ports selected", "message": "Please select at least one COM port in the program's settings." }, + "trackerIMUError": { + "title": "Tracker IMU error", + "message": "Failed to process IMU data from a tracker after many attempts, please restart the connection and check log files for more information." + }, "trackerWriteError": { "title": "Tracker write error", - "message": "Failed to write data to the tracker, please check log files for more information." + "message": "Failed to write data to a tracker, please check log files for more information." }, "trackerReadError": { "title": "Tracker read error", - "message": "Failed to read data from the tracker, please check log files for more information." + "message": "Failed to read data from a tracker, please check log files for more information." }, "unexpectedError": { "title": "Unexpected error", diff --git a/src/main.ts b/src/main.ts index 587eaef..3c2b205 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1103,7 +1103,9 @@ import { ParsedUrlQueryInput } from "querystring"; // For haritorax-interpreter // Used to handle errors coming from haritorax-interpreter and display them to the user if wanted enum ErrorType { + SerialNotFoundRetryError = "Error while retrying connection", SerialNotFoundError = "File not found", + SerialNotOpenError = "Port is not open", SerialOpenError = "Opening COM", SerialWriteError = "Error writing data to serial port", SendHeartbeatError = "Error while sending heartbeat", @@ -1132,6 +1134,8 @@ enum ErrorType { const lastErrorShownTime: Record = { [ErrorType.SerialNotFoundError]: 0, + [ErrorType.SerialNotFoundRetryError]: 0, + [ErrorType.SerialNotOpenError]: 0, [ErrorType.SerialOpenError]: 0, [ErrorType.SerialWriteError]: 0, [ErrorType.SendHeartbeatError]: 0, @@ -1320,6 +1324,7 @@ function startDeviceListeners() { }, 750); }); + let imuErrorCount: { [key: string]: number } = {}; device.on("imu", async (trackerName: string, rawRotation: Rotation, rawGravity: Gravity) => { if (!trackerName || !rawRotation || !rawGravity || !connectedDevices.has(trackerName) || isClosing) return; @@ -1354,6 +1359,16 @@ function startDeviceListeners() { )}`, "tracker" ); + + // Prevent spam of IMU errors + imuErrorCount[trackerName] = imuErrorCount[trackerName] ? imuErrorCount[trackerName] + 1 : 1; + if (imuErrorCount[trackerName] > 20) { + error(`Too many errors processing IMU data for "${trackerName}", disconnecting...`, "tracker"); + device.emit("disconnect", trackerName); + connectedDevices.delete(trackerName); + imuErrorCount[trackerName] = 0; + mainWindow.webContents.send("device-error", trackerName); + } return; } @@ -1448,7 +1463,9 @@ function startDeviceListeners() { device.on("error", (msg: string, exceptional: boolean) => { const handledErrorTypes = [ + ErrorType.SerialNotFoundRetryError, ErrorType.SerialNotFoundError, + ErrorType.SerialNotOpenError, ErrorType.SerialOpenError, ErrorType.BluetoothOpenError, ErrorType.BluetoothScanError, @@ -1478,6 +1495,10 @@ function startDeviceListeners() { if (matchedErrorType) { switch (matchedErrorType) { + case ErrorType.SerialNotFoundRetryError: + case ErrorType.SerialNotOpenError: + handleError(msg, matchedErrorType, handleConnectionRetryError); + break; case ErrorType.SerialNotFoundError: case ErrorType.SerialOpenError: case ErrorType.BluetoothOpenError: @@ -1532,6 +1553,12 @@ function handleError(msg: string, errorType: ErrorType, handler: (msg: string) = } } +async function handleConnectionRetryError(err: any) { + error(`Failed to retry tracker connection`, "haritorax-interpreter", err); + connectedDevices.clear(); + mainWindow.webContents.send("disconnect", "connection-error"); +} + async function handleConnectionStartError(err: any) { error(`Failed to start tracker connection`, "haritorax-interpreter", err); mainWindow.webContents.send("set-status", "main.status.failed"); @@ -1540,6 +1567,7 @@ async function handleConnectionStartError(err: any) { await translate("dialogs.connectionFailed.message") ); + connectedDevices.clear(); mainWindow.webContents.send("disconnect", "connection-error"); } diff --git a/src/static/js/index.ts b/src/static/js/index.ts index a207326..e2e5f47 100644 --- a/src/static/js/index.ts +++ b/src/static/js/index.ts @@ -621,6 +621,14 @@ window.ipc.on("device-connected-to-server", (_event, deviceID) => { window.ipc.invoke("fire-tracker-mag", deviceID); }); +window.ipc.on("device-error", (_event, deviceID) => { + if (!deviceID || !isActive) return; + + window.log(`Too many IMU processing errors with device "${deviceID}"`, "tracker"); + setStatus("main.status.failed"); + showErrorDialog("dialogs.trackerIMUError.title", "dialogs.trackerIMUError.message"); +}); + window.ipc.on("device-data", async (_event: any, arg) => { const { trackerName, rotation, gravity, rawRotation, rawGravity } = arg;