Benjamin-Stefan / ant-plus-next

A modern Node.js library for interacting with ANT+ USB sticks and sensors. Supports both Node.js (USB) and WebUSB (browser) for heart rate monitors, speed sensors, and more.
MIT License
2 stars 0 forks source link

[BUG] Crash when GarminStick3.open() throws exception #35

Closed edabe closed 2 weeks ago

edabe commented 2 weeks ago

Hello Benjamin, While prototyping with your lib, I ran into an error and there might be a simple fix.

Describe the bug If GarminStick3.open() throws an exception, the app will crash with a huge print-out of the entire index.cjs followed by:

TypeError: Right-hand side of 'instanceof' is not an object
    at exports.GarminStick3.<anonymous> (/Users/eabe/Library/Mobile Documents/com~apple~CloudDocs/Development/node/ant-plus-next/dist/index.cjs:1:7434)
    at Generator.next (<anonymous>)
    at /Users/eabe/Library/Mobile Documents/com~apple~CloudDocs/Development/node/ant-plus-next/dist/index.cjs:1:337
    at new Promise (<anonymous>)
    at s (/Users/eabe/Library/Mobile Documents/com~apple~CloudDocs/Development/node/ant-plus-next/dist/index.cjs:1:82)
    at exports.GarminStick3.open (/Users/eabe/Library/Mobile Documents/com~apple~CloudDocs/Development/node/ant-plus-next/dist/index.cjs:1:7029)
    at main (/Users/eabe/Library/Mobile Documents/com~apple~CloudDocs/Development/node/ant-plus-next-test/dist/sensor.js:44:35)
    at Object.<anonymous> (/Users/eabe/Library/Mobile Documents/com~apple~CloudDocs/Development/node/ant-plus-next-test/dist/sensor.js:52:1)
    at Module._compile (node:internal/modules/cjs/loader:1241:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)

This is likely because of a bug in node-usb where the LibUSBException does not properly declares a custom Error class (prototype chain not properly set)

To Reproduce

  1. In a terminal window, start an app that successfully connects to the ANT+ stick
  2. In a different terminal window, start another app that will attempt to connect to the ANT+ stick (but it will fail since it is already being used)

Expected behavior The second app should fail gracefully indicating why the connection to the ANT+ stick failed.

Screenshots N/A

Environment (please complete the following information):

Additional context N/!

Proposed fix This seems to be the recommended way to handle LibUSBException errors: https://github.com/node-usb/node-usb/blob/15781f02baa1f6c856a8d03968de9abd64c4f880/tsc/usb/device.ts#L34

Based on that:

diff --git a/src/core/driver/nodeUSBDriver.ts b/src/core/driver/nodeUSBDriver.ts
index 483990f..097f21c 100644
--- a/src/core/driver/nodeUSBDriver.ts
+++ b/src/core/driver/nodeUSBDriver.ts
@@ -210,8 +210,8 @@ export class NodeUSBDriver extends EventEmitter implements USBDriverBase {
                 this.iface.claim();
                 break;
             } catch (error) {
-                if (error instanceof LibUSBException && this.throwLibUSBException) {
-                    switch (error.errno) {
+                if (error && this.throwLibUSBException) {
+                    switch ((error as LibUSBException).errno) {
                         case usb.usb.LIBUSB_ERROR_ACCESS:
                             throw new Error("LIBUSB_ERROR_ACCESS: Access denied (insufficient permissions)");
                         case usb.usb.LIBUSB_ERROR_NO_DEVICE:
Benjamin-Stefan commented 2 weeks ago

Hello edabe,

Thank you for finding and reporting a bug. I'll take a look at it and fix it.

Best regards, Benjamin

Benjamin-Stefan commented 2 weeks ago

The bug has been fixed, if it works for you too, then the issue can be closed.

Happy coding!

Best regards, Benjamin

edabe commented 2 weeks ago

Hello Benjamin, Thank you for such a quick turnaround.

Yes, I tried the fix locally and it worked fine!