mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-14 10:35:11 +00:00
usb/sagas: Retry USB device open on Linux if SecurityError occurs
On slow machines, udev rules may not have finished processing by the time we try to open the USB device. This causes a SecurityError, so we add a retry loop to handle this case. Closes: https://github.com/pybricks/support/issues/2372
This commit is contained in:
+23
-8
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2025 The Pybricks Authors
|
||||
// Copyright (c) 2025-2026 The Pybricks Authors
|
||||
|
||||
import { firmwareVersion } from '@pybricks/firmware';
|
||||
import { AnyAction } from 'redux';
|
||||
@@ -128,6 +128,7 @@ function* handleUsbConnectPybricks(hotPlugDevice?: USBDevice): Generator {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: show unexpected error message to user here
|
||||
console.error('Failed to request USB device:', reqDeviceErr);
|
||||
yield* put(usbDidFailToConnectPybricks());
|
||||
yield* cleanup();
|
||||
@@ -140,13 +141,27 @@ function* handleUsbConnectPybricks(hotPlugDevice?: USBDevice): Generator {
|
||||
usbDevice = hotPlugDevice;
|
||||
}
|
||||
|
||||
const [, openErr] = yield* call(() => maybe(usbDevice.open()));
|
||||
if (openErr) {
|
||||
// TODO: show error message to user here
|
||||
console.error('Failed to open USB device:', openErr);
|
||||
yield* put(usbDidFailToConnectPybricks());
|
||||
yield* cleanup();
|
||||
return;
|
||||
for (let retry = 1; ; retry++) {
|
||||
const [, openErr] = yield* call(() => maybe(usbDevice.open()));
|
||||
if (openErr) {
|
||||
// On Linux/Android, the udev rules could still be processing, try
|
||||
// a few times before giving up.
|
||||
if (openErr.name === 'SecurityError' && retry <= 5) {
|
||||
console.debug(
|
||||
`Retrying USB device open (${retry}/5) after SecurityError on Linux`,
|
||||
);
|
||||
yield* delay(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: show error message to user here
|
||||
console.error('Failed to open USB device:', openErr);
|
||||
yield* put(usbDidFailToConnectPybricks());
|
||||
yield* cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
exitStack.push(() => usbDevice.close().catch(console.debug));
|
||||
|
||||
Reference in New Issue
Block a user