raise instead of overwriting the config file on syntax error
This commit is contained in:
@@ -27,7 +27,7 @@ import os
|
||||
import signal
|
||||
import sys
|
||||
import threading
|
||||
from typing import Optional, TYPE_CHECKING, List, Sequence
|
||||
from typing import Optional, TYPE_CHECKING, List, Sequence, Union
|
||||
|
||||
try:
|
||||
import PyQt6
|
||||
@@ -582,3 +582,25 @@ class ElectrumGui(BaseElectrumGui, Logger):
|
||||
message = _("Text copied to Clipboard") if title is None else _("{} copied to Clipboard").format(title)
|
||||
# tooltip cannot be displayed immediately when called from a menu; wait 200ms
|
||||
self.timer.singleShot(200, lambda: QToolTip.showText(QCursor.pos(), message, None))
|
||||
|
||||
|
||||
def standalone_exception_dialog(exception: Union[str, BaseException]) -> None:
|
||||
app = QApplication.instance()
|
||||
if not app:
|
||||
app = QApplication([])
|
||||
|
||||
msg_box = QMessageBox()
|
||||
msg_box.setWindowTitle(_("Error starting Electrum"))
|
||||
msg_box.setIcon(QMessageBox.Icon.Critical)
|
||||
msg_box.setText(_("An error occurred") + ":")
|
||||
msg_box.setInformativeText(str(exception))
|
||||
|
||||
# Add detailed traceback if available
|
||||
if hasattr(exception, "__traceback__"):
|
||||
import traceback
|
||||
detailed_text = ''.join(traceback.format_exception(
|
||||
type(exception), exception, exception.__traceback__)
|
||||
)
|
||||
msg_box.setDetailedText(detailed_text)
|
||||
|
||||
msg_box.exec()
|
||||
|
||||
@@ -900,9 +900,7 @@ def read_user_config(path: Optional[str]) -> Dict[str, Any]:
|
||||
with open(config_path, "r", encoding='utf-8') as f:
|
||||
data = f.read()
|
||||
result = json.loads(data)
|
||||
except Exception as exc:
|
||||
_logger.warning(f"Cannot read config file at {config_path}: {exc}")
|
||||
return {}
|
||||
if not type(result) is dict:
|
||||
return {}
|
||||
assert isinstance(result, dict), "config file is not a dict"
|
||||
except Exception as e:
|
||||
raise ValueError(f"Invalid config file at {config_path}: {str(e)}")
|
||||
return result
|
||||
|
||||
25
run_electrum
25
run_electrum
@@ -271,6 +271,25 @@ def sys_exit(i):
|
||||
loop_thread.join(timeout=1)
|
||||
sys.exit(i)
|
||||
|
||||
def read_config(config_options: dict) -> SimpleConfig:
|
||||
"""
|
||||
Reads the config file and returns SimpleConfig, on failure it will potentially
|
||||
show a GUI error dialog if a gui is available, and then re-raise the exception.
|
||||
"""
|
||||
try:
|
||||
return SimpleConfig(config_options)
|
||||
except Exception as config_error:
|
||||
# parse full cmd to find out which UI is being used
|
||||
full_config_options = parse_command_line(simple_parser=False)
|
||||
if full_config_options.get("cmd") == 'gui':
|
||||
gui_name = full_config_options.get(SimpleConfig.GUI_NAME.key(), 'qt')
|
||||
try:
|
||||
gui = __import__(f'electrum.gui.{gui_name}', fromlist=['electrum'])
|
||||
gui.standalone_exception_dialog(config_error) # type: ignore
|
||||
except Exception as e:
|
||||
print_stderr(f"Error showing standalone gui dialog: {e}")
|
||||
raise
|
||||
|
||||
def parse_command_line(simple_parser=False) -> Dict:
|
||||
# parse command line from sys.argv
|
||||
if simple_parser:
|
||||
@@ -371,14 +390,14 @@ def main():
|
||||
sys.argv.remove(x)
|
||||
# parse first without plugins
|
||||
config_options = parse_command_line(simple_parser=True)
|
||||
tmp_config = SimpleConfig(config_options)
|
||||
tmp_config = read_config(config_options)
|
||||
# load (only) the commands modules of plugins so their commands are registered
|
||||
plugin_commands = Plugins(tmp_config, cmd_only=True)
|
||||
_plugin_commands = Plugins(tmp_config, cmd_only=True)
|
||||
# re-parse command line
|
||||
sys.argv = saved_sys_argv[:]
|
||||
config_options = parse_command_line()
|
||||
|
||||
config = SimpleConfig(config_options)
|
||||
config = read_config(config_options)
|
||||
cmdname = config.get('cmd')
|
||||
|
||||
# set language as early as possible
|
||||
|
||||
@@ -6,7 +6,6 @@ import shutil
|
||||
from io import StringIO
|
||||
|
||||
from electrum.simple_config import SimpleConfig, read_user_config
|
||||
from electrum import constants
|
||||
|
||||
from . import ElectrumTestCase
|
||||
|
||||
@@ -250,5 +249,5 @@ class TestUserConfig(ElectrumTestCase):
|
||||
with open(thefile, "w") as f:
|
||||
f.write(repr(payload))
|
||||
|
||||
result = read_user_config(self.user_dir)
|
||||
self.assertEqual({}, result)
|
||||
with self.assertRaises(ValueError):
|
||||
read_user_config(self.user_dir)
|
||||
|
||||
Reference in New Issue
Block a user