From 483acd57414ae6cf137664d4a074da67bfa23833 Mon Sep 17 00:00:00 2001 From: keeramis Date: Tue, 30 Jan 2024 10:11:21 -0800 Subject: [PATCH 1/3] Propagate errors correctly with device mode checks --- src/cmd/usb-util.js | 8 ++++++-- src/cmd/usb.js | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/cmd/usb-util.js b/src/cmd/usb-util.js index b211c3ffb..83e457822 100644 --- a/src/cmd/usb-util.js +++ b/src/cmd/usb-util.js @@ -7,7 +7,8 @@ const { openDeviceById, NotFoundError, NotAllowedError, - TimeoutError + TimeoutError, + DeviceProtectionError } = require('../lib/require-optional')('particle-usb'); // Timeout when reopening a USB device after an update via control requests. This timeout should be @@ -35,6 +36,8 @@ async function _getDeviceInfo(device) { } catch (err) { if (err instanceof TimeoutError) { return { id, mode: 'UNKNOWN' }; + } else if (err instanceof DeviceProtectionError) { + throw new Error('Operation could not be completed due to device protection.'); } else { throw new Error(`Unable to get device mode: ${err.message}`); } @@ -362,5 +365,6 @@ module.exports = { reopenInNormalMode, reopenDevice, UsbPermissionsError, - TimeoutError + TimeoutError, + DeviceProtectionError }; diff --git a/src/cmd/usb.js b/src/cmd/usb.js index 39bef2033..6a3e763ac 100644 --- a/src/cmd/usb.js +++ b/src/cmd/usb.js @@ -1,7 +1,7 @@ const { spin } = require('../app/ui'); const { delay, asyncMapSeries, buildDeviceFilter } = require('../lib/utilities'); const { getDevice, formatDeviceInfo } = require('./device-util'); -const { getUsbDevices, openUsbDevice, openUsbDeviceByIdOrName, TimeoutError } = require('./usb-util'); +const { getUsbDevices, openUsbDevice, openUsbDeviceByIdOrName, TimeoutError, DeviceProtectionError } = require('./usb-util'); const { systemSupportsUdev, udevRulesInstalled, installUdevRules } = require('./udev'); const { platformForId, isKnownPlatformId } = require('../lib/platform'); const ParticleApi = require('./api'); @@ -46,8 +46,10 @@ module.exports = class UsbCommand { info.push( usbDevice.getDeviceMode({ timeout: 10 * 1000 }) .catch(error => { - if (error instanceof TimeoutError){ + if (error instanceof TimeoutError) { return 'UNKNOWN'; + } else if (error instanceof DeviceProtectionError) { + return; } throw error; }) From 8e75da8995088cb6d3d36444b27b98cb9e063305 Mon Sep 17 00:00:00 2001 From: keeramis Date: Tue, 30 Jan 2024 11:23:59 -0800 Subject: [PATCH 2/3] Add protected msg in the UI --- src/cmd/usb.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/usb.js b/src/cmd/usb.js index 6a3e763ac..e1fbd843f 100644 --- a/src/cmd/usb.js +++ b/src/cmd/usb.js @@ -49,7 +49,7 @@ module.exports = class UsbCommand { if (error instanceof TimeoutError) { return 'UNKNOWN'; } else if (error instanceof DeviceProtectionError) { - return; + return 'PROTECTED'; } throw error; }) From fb602a38891519d6a143a42b555e5e8500477750 Mon Sep 17 00:00:00 2001 From: keeramis Date: Tue, 30 Jan 2024 12:04:43 -0800 Subject: [PATCH 3/3] Handle multiple devices --- src/cmd/usb-util.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cmd/usb-util.js b/src/cmd/usb-util.js index 83e457822..77d4eba2f 100644 --- a/src/cmd/usb-util.js +++ b/src/cmd/usb-util.js @@ -37,7 +37,7 @@ async function _getDeviceInfo(device) { if (err instanceof TimeoutError) { return { id, mode: 'UNKNOWN' }; } else if (err instanceof DeviceProtectionError) { - throw new Error('Operation could not be completed due to device protection.'); + return { id, mode: 'PROTECTED' }; } else { throw new Error(`Unable to get device mode: ${err.message}`); } @@ -242,6 +242,11 @@ async function getOneUsbDevice({ idOrName, api, auth, ui, flashMode, platformId usbDevice = devices[0].value; } + const devInfo = await _getDeviceInfo(usbDevice); + if (devInfo.mode === 'PROTECTED') { + ui.write(`Attempted to flash device ${devInfo.id}`); + throw new Error('Operation could not be completed due to device protection.'); + } try { await usbDevice.open();