Web app can get wedged in state where it fails silently until Chrome is restarted
Last night I was seeing a problem where all Rebeltech Dot Org web apps that connect to my Magus would fail silently every time— no error message but also nothing would happen. This morning I restarted Chrome and the problem went away instantly. I have now found I can reproduce this problem 100% of the time by connecting a web app to the Magus and then unplugging and re-plugging the Magus while a browser tab is "connected" to the device.
Configuration
My device is a 2019 Magus running v22.4.0 installed from the Github releases page, with some version of MidiBoot2 installed by hand. In all tests the Magus was being powered from the USB port marked USB-DEVICE.
My PC is running:
Google Chrome | 102.0.5005.63 (Official Build) (64-bit) (cohort: Stable) Revision | 0e59bcc00cc4985ce39ad31c150065f159d95ad3-refs/branch-heads/5005@{#819} OS | Windows 10 Version 21H1 (Build 19043.1706)
Last night I was running Chrome 102.0.5005.62 (102_win_rampup) but the symptoms were the same. (Chrome updated when I restarted it this morning.)
I have a MacBook I could test on, but I haven't tried this yet.
Repro steps
I have been testing with this patch and this patch. I don't think the patch matters but these are minimal patches that make no sound but the second patch writes to the Magus screen. The steps are
- Open a tab with the "Silence" patch. Connect to device. Click "Store" and store as patch 1.
- Open a tab with the "ScreenSaver" patch.
- Disconnect and reconnect the USB-DEVICE plug from the Magus.
- Click "Connect to Device" in the "ScreenSaver" tab.
Observed behavior
At this point, the web app cannot talk to the Magus, but for some reason it thinks it can. The "Patch" app will show the "Load" and "Store" buttons, and will allow you to click "Store" and upload a patch with no errors. The "Device" app will allow you to connect and click "Erase storage", and it will complete with no errors. However no patches are stored, the memory is not cleared etc. The telltale you are in this state is that the Patch app will show "Load" and "Store" but will not show the status lines underneath ("Loaded Patch", "Firmware", "UUID" etc).
In my tests I think the bug reproduces even if you swap the order of steps 2 and 3, IE, you can unplug and replug the Magus and open the new tab afterward and still get the bug. However, if you connect in tab A, close tab A, then unplug and replug, then open tab B and connect in tab B, tab B will work perfectly correctly. A tab must be open and connected when you unplug/replug the Magus to get in the broken state. However once you get in the broken state the only way to get out is to close and reopen Chrome completely, closing tabs alone will not fix it.
Here is a picture of the Patch app while in broken state:

Notice no status lines under Store, and notice that the JavaScript console prints the entire sequence of uploading the patch as if it were succeeding.
In two of my tests this morning, once the browser got into the "broken state", attempting to close my Rebeltech Dot Org tabs actually hardlocked Chrome!

The window stopped responding to all mouse input, I could not close the window or change tabs, and one of the two times I saw this right-clicking would draw a menu shadow but no menu. I had to force quit Chrome both times.
"Expected behavior"
So obviously preferably this should not happen. But also
-
The web app should not fail silently. It would not have taken me so long to understand the problem if I had got any error messages at all. When I click "connect to device" while Chrome is in broken state, it should either display an error, or after a second of no response from the device it should display "No response from device" underneath Load/Store. If I Store or Erase Storage while in broken state, it should show an error. The web app can clearly detect that the broken state is occurring because in broken state it does not print the status lines.
-
A bug should be filed on Chrome. It should not be possible for a web app to break in a way that persists past closing and reopening all of that web app's tabs (unless maybe you are using a shared worker, but I checked and I do not think you are?). It should definitely not be possible to crash Chrome. Either the web app is doing something that breaks Chrome or the USB driver inside the Magus is doing something that breaks Windows in a way that breaks Chrome. Either way Chrome should be fully resilient to that and it is a security issue they should fix if they are not. I would be happy to file this bug on Chromium myself but it would be helpful first to know if this is a bug in the web app or in the device/Windows/WebMIDI chain.
Update, just now I was able to hardlock Chrome just by disconnecting the magus while a Patch tab was connected, I didn't even need to plug it back in.
This turns out to make upgrading the firmware a little tricky because in 100% of my tests the Firmware update page, when you click "Reset to Boot Loader" or "Device Reset", the device disconnecting will immediately hardlock Chrome and I have to force quit it. LOL
There's a bug in Windows that is triggered by USB MIDI devices resetting unexpectedly, and for some reason it is particularly troublesome with Web MIDI. It is sometimes fixed by killing all Chrome processes (including the dozen or so hidden ones), while other times only a reboot will restore the system. I've not seen it officially described anywhere, but it's definitely a thing.
A company I worked with a few years ago tried to find a solution or workaround; some combination of Windows version, USB drivers, Chrome and configuration that worked reliably in a reproducible way. Alas, no: some machines would always hang or crash, others never, with no discernible commonality or pattern.
The problem of course is that we depend on resetting the device in order to enter USB Bootloader mode. I think your suggestion @mcclure of disconnecting in the web app is a good one (issue #75), but I suspect that the underlying drivers will still preserve state and still crash.
It is quite possible to flash the bootloader from the main firmware directly, if we decide to implement that. It's something we used to support in OwlWare, before we had the USB MIDI Bootloader. It's a bit tricky, because all the code that is invoked while the device is flashed must run from RAM (the firmware otherwise executes from flash). And at the end of it you still have to reset the device, so it only goes some way to fixing the problem.
It is quite possible to flash the bootloader from the main firmware directly, if we decide to implement that.
But flashing bootloader from firmware is supported (thanks to me!). Did you mean flashing firmware without going to bootloader mode perhaps?
some machines would always hang or crash, others never, with no discernible commonality or pattern
Hm, I see. It is mostly interesting to me because I do not think I ever saw this before 22.4. But of course probably Windows has updated since I last used my Magus also.
Do you know if there is a Chrome bug for this already? If not perhaps I will file one on them. (Even if the operating system is causing it, a modern browser should be resistant to operating system's attempts to crash it. 🙂)