oasis-wallet-web
oasis-wallet-web copied to clipboard
Ledger crashes after enumerating twice without waiting
Crash
- After https://github.com/oasisprotocol/oasis-wallet-web/pull/864/commits/4eb371ed17652bb7ef617a1765989abca54b40a5
- open /open-wallet/ledger
- click "Select accounts to open"
- quickly press Esc
- click "Select accounts to open"
- Enumerating never finishes, and Ledger device needs to be restarted
This probably happens because takeEvery
calls enumerateAccounts
again, calling getUSBTransport
before old transport.close
https://github.com/oasisprotocol/oasis-wallet-web/blob/ad9591363d53216551537d37603ff67fb01fa2e4/src/app/state/ledger/saga.ts#L92
https://github.com/oasisprotocol/oasis-wallet-web/blob/ad9591363d53216551537d37603ff67fb01fa2e4/src/app/state/ledger/saga.ts#L72-L74
Solution
If we used takeLatest
, it would cancel old enumerateAccounts
and call transport.close
first, before calling enumerateAccounts
again. But cancellation doesn't wait for finally
to finish https://redux-saga.js.org/docs/advanced/TaskCancellation/#note, so it still doesn't work.
Maybe reimplement takeLatest
with additional timeout?
export function* ledgerSaga() {
let enumerateTask = null
// Reimplemented `takeLatest` with additional delay after canceling
// TODO: Probably need to use actionChannel?
while (yield* take(ledgerActions.enumerateAccounts)) {
if (enumerateTask?.isRunning()) {
yield* cancel(enumerateTask)
// Workaround: `cancel` doesn't wait for `finally` to finish
// https://redux-saga.js.org/docs/advanced/TaskCancellation/#note
yield delay(2000)
}
enumerateTask = yield* fork(enumerateAccounts)
}
Maybe just disable Esc again, and write a long comment?