1
0

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:
SomberNight
2018-11-08 19:46:15 +01:00
parent dace2e5495
commit bd32b88f62
10 changed files with 70 additions and 59 deletions

View File

@@ -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