From 4023ab9bd57589fcdbf77d72266effd617ed6515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Fri, 12 Dec 2025 15:18:24 +0100 Subject: [PATCH] feat: better handling of corrupted updates --- src/lib/serial/device.ts | 3 +- .../ccos/[device]/[version]/+page.svelte | 79 +++++++++++++++---- 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/src/lib/serial/device.ts b/src/lib/serial/device.ts index 2c40c505..1617f6b1 100644 --- a/src/lib/serial/device.ts +++ b/src/lib/serial/device.ts @@ -64,6 +64,7 @@ const KEY_COUNTS = { TWO: 90, LITE: 67, X: 256, + ENGINE: 256, M4G: 90, M4GR: 90, T4G: 7, @@ -157,7 +158,7 @@ export class CharaDevice { constructor( private readonly port: SerialPortLike, - private readonly baudRate = 115200, + public baudRate = 115200, ) {} async init() { diff --git a/src/routes/(app)/ccos/[device]/[version]/+page.svelte b/src/routes/(app)/ccos/[device]/[version]/+page.svelte index 402a3512..dda143c7 100644 --- a/src/routes/(app)/ccos/[device]/[version]/+page.svelte +++ b/src/routes/(app)/ccos/[device]/[version]/+page.svelte @@ -10,7 +10,9 @@ let working = $state(false); let success = $state(false); - let error = $state(undefined); + let error = $state( + new Error("ESP_ERR_OTA_VALIDATE_FAILED"), + ); let isTooOld = $derived( $serialPort ? semverLt($serialPort.version, "2.0.0") : false, @@ -32,21 +34,45 @@ success = false; const port = $serialPort!; $serialPort = undefined; - try { - const file = await fetch( - `${data.meta.path}/${data.meta.update.ota}`, - ).then((it) => it.arrayBuffer()); - await port.updateFirmware(file, (transferred, total) => { - progress = transferred / total; - }); + let file: ArrayBuffer | undefined; + let retries = 3; + let err: Error | undefined = undefined; - success = true; - } catch (e) { - error = e as Error; - } finally { - working = false; + while (!file && retries-- > 0) { + try { + file = await fetch(`${data.meta.path}/${data.meta.update.ota}`).then( + (it) => it.arrayBuffer(), + ); + } catch (e) { + err = e as Error; + } } + + if (!file) { + error = err; + working = false; + return; + } + + retries = 2; + while (retries-- > 0 && !success) { + try { + await port.updateFirmware(file, (transferred, total) => { + progress = transferred / total; + }); + + success = true; + } catch (e) { + err = e as Error; + port.baudRate = 9600; + } + } + + if (!success) { + error = err; + } + working = false; } let currentDevice = $derived( @@ -237,7 +263,32 @@ {:else if success}
Update successful
{:else if error} -
{error.message}
+
+ {#if error.message.includes("ESP_ERR_OTA_VALIDATE_FAILED")} + Update corrupted during transmission +
    +
  • + Double-check your USB cable is fully seated on both ends +
  • +
  • Remove any USB hubs between the device and the computer
  • +
  • Unplug all other USB devices
  • +
  • Don't touch the device or your computer during the update
  • +
  • Try using a different USB cable
  • +
  • Try using a different USB Port
  • +
  • Try the update again a few times
  • + {#if navigator.userAgent.includes("Macintosh")} +
  • + Try updating on either Windows, Linux or ChromeOS instead of + MacOS +
  • + {/if} +
+ DO NOT USE THE UNSAFE RECOVERY OPTIONS, they bypass + corruption checks an can soft-brick your device. + {:else} + {error.message} + {/if} +
{:else if working}
Updating your device...
{:else}