1
0

commands: add clear error that plugin commands cannot be run with -o

note that atm none of the plugin commands are explicitly marked with 'n' but all require it.
Also note that 'w' for plugin commands kind of implies 'n' anyway, as the 'load_wallet' hook relies on having a daemon.

```
$ ./run_electrum -o --testnet labels_pull
Password:
  1.96 | E | __main__ | error running command (without daemon)
Traceback (most recent call last):
  File "/home/user/wspace/electrum/./run_electrum", line 587, in handle_cmd
    result = fut.result()
  File "/usr/lib/python3.13/concurrent/futures/_base.py", line 456, in result
    return self.__get_result()
           ~~~~~~~~~~~~~~~~~^^
  File "/usr/lib/python3.13/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/home/user/wspace/electrum/./run_electrum", line 267, in run_offline_command
    result = await func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/wspace/electrum/electrum/commands.py", line 202, in func_wrapper
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/wspace/electrum/electrum/commands.py", line 2214, in func_wrapper
    kwargs['plugin'] = daemon._plugins.get_plugin(plugin_name)
                       ^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '_plugins'
```
This commit is contained in:
SomberNight
2025-09-05 18:23:49 +00:00
parent 1e55ee8ea2
commit 7455cf9dec

View File

@@ -114,7 +114,7 @@ def format_satoshis(x: Union[float, int, Decimal, None]) -> Optional[str]:
class Command:
def __init__(self, func, name, s):
self.name = name
self.requires_network = 'n' in s
self.requires_network = 'n' in s # better name would be "requires daemon"
self.requires_wallet = 'w' in s
self.requires_password = 'p' in s
self.requires_lightning = 'l' in s
@@ -2198,6 +2198,9 @@ class Commands(Logger):
def plugin_command(s, plugin_name):
"""Decorator to register a cli command inside a plugin. To be used within a commands.py file
in the plugins root."""
# atm all plugin commands require a daemon, cannot be run in 'offline' mode:
if 'n' not in s:
s += 'n'
def decorator(func):
assert len(plugin_name) > 0, "Plugin name must not be empty"
func.plugin_name = plugin_name
@@ -2211,6 +2214,7 @@ def plugin_command(s, plugin_name):
async def func_wrapper(*args, **kwargs):
cmd_runner = args[0] # type: Commands
daemon = cmd_runner.daemon
assert daemon is not None
kwargs['plugin'] = daemon._plugins.get_plugin(plugin_name)
return await func(*args, **kwargs)