feat: better handling of corrupted updates

This commit is contained in:
2025-12-12 15:18:24 +01:00
parent 2893afa2ba
commit 4023ab9bd5
2 changed files with 67 additions and 15 deletions

View File

@@ -64,6 +64,7 @@ const KEY_COUNTS = {
TWO: 90, TWO: 90,
LITE: 67, LITE: 67,
X: 256, X: 256,
ENGINE: 256,
M4G: 90, M4G: 90,
M4GR: 90, M4GR: 90,
T4G: 7, T4G: 7,
@@ -157,7 +158,7 @@ export class CharaDevice {
constructor( constructor(
private readonly port: SerialPortLike, private readonly port: SerialPortLike,
private readonly baudRate = 115200, public baudRate = 115200,
) {} ) {}
async init() { async init() {

View File

@@ -10,7 +10,9 @@
let working = $state(false); let working = $state(false);
let success = $state(false); let success = $state(false);
let error = $state<Error | undefined>(undefined); let error = $state<Error | undefined>(
new Error("ESP_ERR_OTA_VALIDATE_FAILED"),
);
let isTooOld = $derived( let isTooOld = $derived(
$serialPort ? semverLt($serialPort.version, "2.0.0") : false, $serialPort ? semverLt($serialPort.version, "2.0.0") : false,
@@ -32,21 +34,45 @@
success = false; success = false;
const port = $serialPort!; const port = $serialPort!;
$serialPort = undefined; $serialPort = undefined;
try {
const file = await fetch(
`${data.meta.path}/${data.meta.update.ota}`,
).then((it) => it.arrayBuffer());
await port.updateFirmware(file, (transferred, total) => { let file: ArrayBuffer | undefined;
progress = transferred / total; let retries = 3;
}); let err: Error | undefined = undefined;
success = true; while (!file && retries-- > 0) {
} catch (e) { try {
error = e as Error; file = await fetch(`${data.meta.path}/${data.meta.update.ota}`).then(
} finally { (it) => it.arrayBuffer(),
working = false; );
} 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( let currentDevice = $derived(
@@ -237,7 +263,32 @@
{:else if success} {:else if success}
<div class="primary" transition:slide>Update successful</div> <div class="primary" transition:slide>Update successful</div>
{:else if error} {:else if error}
<div class="error" transition:slide>{error.message}</div> <div class="error" transition:slide>
{#if error.message.includes("ESP_ERR_OTA_VALIDATE_FAILED")}
<b>Update corrupted during transmission</b>
<ul>
<li>
Double-check your USB cable is <b>fully seated</b> on both ends
</li>
<li>Remove any USB hubs between the device and the computer</li>
<li>Unplug all other USB devices</li>
<li>Don't touch the device or your computer during the update</li>
<li>Try using a different USB cable</li>
<li>Try using a different USB Port</li>
<li>Try the update again a few times</li>
{#if navigator.userAgent.includes("Macintosh")}
<li>
Try updating on either Windows, Linux or ChromeOS instead of
MacOS
</li>
{/if}
</ul>
<b>DO NOT USE THE UNSAFE RECOVERY OPTIONS</b>, they bypass
corruption checks an can soft-brick your device.
{:else}
{error.message}
{/if}
</div>
{:else if working} {:else if working}
<div class="primary" transition:slide>Updating your device...</div> <div class="primary" transition:slide>Updating your device...</div>
{:else} {:else}