URI: 
       twizard: better hww debug messages when unpaired_device_infos fails - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit f2ad116b0b03eb57e4c898dda2994a310b6768fd
   DIR parent 5fc715cdee8c54ecb260ac256a5baccecc358e4b
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Mon, 21 Jan 2019 18:44:36 +0100
       
       wizard: better hww debug messages when unpaired_device_infos fails
       
       t[DeviceMgr] scanning devices...
       t[DeviceMgr] failed to create client for ledger at b'0002:0007:00': OSError('open failed',)
       t[DeviceMgr] error getting device infos for ledger: open failed
       
       ^ GUI did not contain any info about failure
       
       Diffstat:
         M electrum/base_wizard.py             |      24 +++++++++++++++++-------
         M electrum/plugin.py                  |      18 +++++++++++-------
       
       2 files changed, 28 insertions(+), 14 deletions(-)
       ---
   DIR diff --git a/electrum/base_wizard.py b/electrum/base_wizard.py
       t@@ -233,16 +233,23 @@ class BaseWizard(object):
                title = _('Hardware Keystore')
                # check available plugins
                supported_plugins = self.plugins.get_hardware_support()
       -        # scan devices
                devices = []  # type: List[Tuple[str, DeviceInfo]]
                devmgr = self.plugins.device_manager
       +        debug_msg = ''
       +
       +        def failed_getting_device_infos(name, e):
       +            nonlocal debug_msg
       +            devmgr.print_error(f'error getting device infos for {name}: {e}')
       +            indented_error_msg = '    '.join([''] + str(e).splitlines(keepends=True))
       +            debug_msg += f'  {name}: (error getting device infos)\n{indented_error_msg}\n'
       +
       +        # scan devices
                try:
                    scanned_devices = devmgr.scan_devices()
                except BaseException as e:
                    devmgr.print_error('error scanning devices: {}'.format(repr(e)))
                    debug_msg = '  {}:\n    {}'.format(_('Error scanning devices'), e)
                else:
       -            debug_msg = ''
                    for splugin in supported_plugins:
                        name, plugin = splugin.name, splugin.plugin
                        # plugin init errored?
       t@@ -256,14 +263,17 @@ class BaseWizard(object):
                        # see if plugin recognizes 'scanned_devices'
                        try:
                            # FIXME: side-effect: unpaired_device_info sets client.handler
       -                    u = devmgr.unpaired_device_infos(None, plugin, devices=scanned_devices)
       +                    device_infos = devmgr.unpaired_device_infos(None, plugin, devices=scanned_devices,
       +                                                                include_failing_clients=True)
                        except BaseException as e:
                            traceback.print_exc()
       -                    devmgr.print_error(f'error getting device infos for {name}: {e}')
       -                    indented_error_msg = '    '.join([''] + str(e).splitlines(keepends=True))
       -                    debug_msg += f'  {name}: (error getting device infos)\n{indented_error_msg}\n'
       +                    failed_getting_device_infos(name, e)
                            continue
       -                devices += list(map(lambda x: (name, x), u))
       +                device_infos_failing = list(filter(lambda di: di.exception is not None, device_infos))
       +                for di in device_infos_failing:
       +                    failed_getting_device_infos(name, di.exception)
       +                device_infos_working = list(filter(lambda di: di.exception is None, device_infos))
       +                devices += list(map(lambda x: (name, x), device_infos_working))
                if not debug_msg:
                    debug_msg = '  {}'.format(_('No exceptions encountered.'))
                if not devices:
   DIR diff --git a/electrum/plugin.py b/electrum/plugin.py
       t@@ -301,8 +301,9 @@ class Device(NamedTuple):
        
        class DeviceInfo(NamedTuple):
            device: Device
       -    label: str
       -    initialized: bool
       +    label: Optional[str] = None
       +    initialized: Optional[bool] = None
       +    exception: Optional[Exception] = None
        
        
        class HardwarePluginToScan(NamedTuple):
       t@@ -500,7 +501,8 @@ class DeviceMgr(ThreadJob, PrintError):
                      'its seed (and passphrase, if any).  Otherwise all bitcoins you '
                      'receive will be unspendable.').format(plugin.device))
        
       -    def unpaired_device_infos(self, handler, plugin: 'HW_PluginBase', devices=None):
       +    def unpaired_device_infos(self, handler, plugin: 'HW_PluginBase', devices=None,
       +                              include_failing_clients=False):
                '''Returns a list of DeviceInfo objects: one for each connected,
                unpaired device accepted by the plugin.'''
                if not plugin.libraries_available:
       t@@ -515,14 +517,16 @@ class DeviceMgr(ThreadJob, PrintError):
                        continue
                    try:
                        client = self.create_client(device, handler, plugin)
       -            except UserFacingException:
       -                raise
       -            except BaseException as e:
       +            except Exception as e:
                        self.print_error(f'failed to create client for {plugin.name} at {device.path}: {repr(e)}')
       +                if include_failing_clients:
       +                    infos.append(DeviceInfo(device=device, exception=e))
                        continue
                    if not client:
                        continue
       -            infos.append(DeviceInfo(device, client.label(), client.is_initialized()))
       +            infos.append(DeviceInfo(device=device,
       +                                    label=client.label(),
       +                                    initialized=client.is_initialized()))
        
                return infos