introduce UserFacingException
we should not raise generic Exception when wanting to communicate with the user. it makes distinguishing programming errors and messages hard, as the caller will necessarily need to catch all Exceptions then
This commit is contained in:
@@ -9,7 +9,7 @@ from electrum.i18n import _
|
||||
from electrum.keystore import Hardware_KeyStore
|
||||
from electrum.transaction import Transaction
|
||||
from electrum.wallet import Standard_Wallet
|
||||
from electrum.util import print_error, bfh, bh2u, versiontuple
|
||||
from electrum.util import print_error, bfh, bh2u, versiontuple, UserFacingException
|
||||
from electrum.base_wizard import ScriptTypeNotSupported
|
||||
|
||||
from ..hw_wallet import HW_PluginBase
|
||||
@@ -46,7 +46,7 @@ def test_pin_unlocked(func):
|
||||
return func(self, *args, **kwargs)
|
||||
except BTChipException as e:
|
||||
if e.sw == 0x6982:
|
||||
raise Exception(_('Your Ledger is locked. Please unlock it.'))
|
||||
raise UserFacingException(_('Your Ledger is locked. Please unlock it.'))
|
||||
else:
|
||||
raise
|
||||
return catch_exception
|
||||
@@ -92,9 +92,9 @@ class Ledger_Client():
|
||||
#self.get_client() # prompt for the PIN before displaying the dialog if necessary
|
||||
#self.handler.show_message("Computing master public key")
|
||||
if xtype in ['p2wpkh', 'p2wsh'] and not self.supports_native_segwit():
|
||||
raise Exception(MSG_NEEDS_FW_UPDATE_SEGWIT)
|
||||
raise UserFacingException(MSG_NEEDS_FW_UPDATE_SEGWIT)
|
||||
if xtype in ['p2wpkh-p2sh', 'p2wsh-p2sh'] and not self.supports_segwit():
|
||||
raise Exception(MSG_NEEDS_FW_UPDATE_SEGWIT)
|
||||
raise UserFacingException(MSG_NEEDS_FW_UPDATE_SEGWIT)
|
||||
splitPath = bip32_path.split('/')
|
||||
if splitPath[0] == 'm':
|
||||
splitPath = splitPath[1:]
|
||||
@@ -154,7 +154,7 @@ class Ledger_Client():
|
||||
|
||||
if not checkFirmware(firmwareInfo):
|
||||
self.dongleObject.dongle.close()
|
||||
raise Exception(MSG_NEEDS_FW_UPDATE_GENERIC)
|
||||
raise UserFacingException(MSG_NEEDS_FW_UPDATE_GENERIC)
|
||||
try:
|
||||
self.dongleObject.getOperationMode()
|
||||
except BTChipException as e:
|
||||
@@ -172,18 +172,18 @@ class Ledger_Client():
|
||||
msg = "Enter your Ledger PIN - WARNING : LAST ATTEMPT. If the PIN is not correct, the dongle will be wiped."
|
||||
confirmed, p, pin = self.password_dialog(msg)
|
||||
if not confirmed:
|
||||
raise Exception('Aborted by user - please unplug the dongle and plug it again before retrying')
|
||||
raise UserFacingException('Aborted by user - please unplug the dongle and plug it again before retrying')
|
||||
pin = pin.encode()
|
||||
self.dongleObject.verifyPin(pin)
|
||||
except BTChipException as e:
|
||||
if (e.sw == 0x6faa):
|
||||
raise Exception("Dongle is temporarily locked - please unplug it and replug it again")
|
||||
raise UserFacingException("Dongle is temporarily locked - please unplug it and replug it again")
|
||||
if ((e.sw & 0xFFF0) == 0x63c0):
|
||||
raise Exception("Invalid PIN - please unplug the dongle and plug it again before retrying")
|
||||
raise UserFacingException("Invalid PIN - please unplug the dongle and plug it again before retrying")
|
||||
if e.sw == 0x6f00 and e.message == 'Invalid channel':
|
||||
# based on docs 0x6f00 might be a more general error, hence we also compare message to be sure
|
||||
raise Exception("Invalid channel.\n"
|
||||
"Please make sure that 'Browser support' is disabled on your device.")
|
||||
raise UserFacingException("Invalid channel.\n"
|
||||
"Please make sure that 'Browser support' is disabled on your device.")
|
||||
raise e
|
||||
|
||||
def checkDevice(self):
|
||||
@@ -192,7 +192,7 @@ class Ledger_Client():
|
||||
self.perform_hw1_preflight()
|
||||
except BTChipException as e:
|
||||
if (e.sw == 0x6d00 or e.sw == 0x6700):
|
||||
raise Exception(_("Device not in Bitcoin mode")) from e
|
||||
raise UserFacingException(_("Device not in Bitcoin mode")) from e
|
||||
raise e
|
||||
self.preflightDone = True
|
||||
|
||||
@@ -238,7 +238,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
|
||||
self.signing = False
|
||||
if clear_client:
|
||||
self.client = None
|
||||
raise Exception(message)
|
||||
raise UserFacingException(message)
|
||||
|
||||
def set_and_unset_signing(func):
|
||||
"""Function decorator to set and unset self.signing."""
|
||||
@@ -258,7 +258,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
|
||||
return address_path[2:]
|
||||
|
||||
def decrypt_message(self, pubkey, message, password):
|
||||
raise RuntimeError(_('Encryption and decryption are currently not supported for {}').format(self.device))
|
||||
raise UserFacingException(_('Encryption and decryption are currently not supported for {}').format(self.device))
|
||||
|
||||
@test_pin_unlocked
|
||||
@set_and_unset_signing
|
||||
@@ -357,7 +357,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
|
||||
redeemScript = Transaction.get_preimage_script(txin)
|
||||
txin_prev_tx = txin.get('prev_tx')
|
||||
if txin_prev_tx is None and not Transaction.is_segwit_input(txin):
|
||||
raise Exception(_('Offline signing with {} is not supported for legacy inputs.').format(self.device))
|
||||
raise UserFacingException(_('Offline signing with {} is not supported for legacy inputs.').format(self.device))
|
||||
txin_prev_tx_raw = txin_prev_tx.raw if txin_prev_tx else None
|
||||
inputs.append([txin_prev_tx_raw,
|
||||
txin['prevout_n'],
|
||||
@@ -586,8 +586,8 @@ class LedgerPlugin(HW_PluginBase):
|
||||
device_id = device_info.device.id_
|
||||
client = devmgr.client_by_id(device_id)
|
||||
if client is None:
|
||||
raise Exception(_('Failed to create a client for this device.') + '\n' +
|
||||
_('Make sure it is in the correct state.'))
|
||||
raise UserFacingException(_('Failed to create a client for this device.') + '\n' +
|
||||
_('Make sure it is in the correct state.'))
|
||||
client.handler = self.create_handler(wizard)
|
||||
client.get_xpub("m/44'/0'", 'standard') # TODO replace by direct derivation once Nano S > 1.1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user