Skip to content

fix: don't fail or crash when the USB bus is missing - #94

Draft
Julusian wants to merge 1 commit into
node-usb:mainfrom
Julusian:fix/crash-in-container
Draft

Julusian wants to merge 1 commit into
node-usb:mainfrom
Julusian:fix/crash-in-container

Conversation

@Julusian

Copy link
Copy Markdown
Contributor

Changes

On Linux machines with no USB bus (often containers), /sys/bus/usb/devices doesn't exist. nusb reports that as an error, so getDevices, findDeviceByIds and findDeviceBySerial all rejected. addEventListener's initial device list had no catch, which caused an unhandled rejection.

Fixes

  • Catches an error thrown due to missing /sys/bus/usb/devices path on linux

I am not 100% sure on some of the TS error changes, but the setTimeout(() => { throw error; }, 0) will always manifest as an uncaughtException unless the application sets up a handler for those errors, in which it is common to exit the application as a means to recover.

Checklist

Have you...

  • Tested the change acts as expected
  • Checked the change doesn't remove or change existing functionality
  • Considered how the feature impacts the product and tested around it (not just the happy paths)
  • Where possible, executed the hardware tests on multiple operating systems

See bitfocus/companion#4522 for the original error

On Linux machines with no USB bus (often containers), /sys/bus/usb/devices
doesn't exist. nusb reports that as an error, so getDevices,
findDeviceByIds and findDeviceBySerial all rejected. addEventListener's
initial device list had no catch, which caused an unhandled rejection.
Comment thread src/lib.rs
Comment on lines 165 to +173

// A Linux machine without a USB bus (often a container) has no
// /sys/bus/usb/devices. That means there are no devices, not that listing failed.
fn is_missing_usb_bus(e: &nusb::Error) -> bool {
cfg!(target_os = "linux")
&& e.os_error().is_some_and(|code| {
std::io::Error::from_raw_os_error(code as i32).kind() == std::io::ErrorKind::NotFound
})
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably just do list_devices().wait().map_or(Vec::new(), |devices| devices.collect()) instead of testing for the specific error, since if you don't want it to fail in that case, you probably don't want it to fail in other cases either.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants