diff options
author | Florian Bruhin <me@the-compiler.org> | 2019-10-11 12:36:28 +0200 |
---|---|---|
committer | Florian Bruhin <me@the-compiler.org> | 2019-11-22 15:24:54 +0100 |
commit | 25e6f103457f89544f99bfcd62bbd78f8a4ce7f3 (patch) | |
tree | ac25cdebd4a08793f99c20bd8deda05559e6270d | |
parent | 9d9c404d4fbc527a75c7c71669a366d6225c4081 (diff) | |
download | qutebrowser-25e6f103457f89544f99bfcd62bbd78f8a4ce7f3.tar.gz qutebrowser-25e6f103457f89544f99bfcd62bbd78f8a4ce7f3.zip |
Handle errors while reading state config
-rw-r--r-- | doc/changelog.asciidoc | 10 | ||||
-rw-r--r-- | qutebrowser/config/configexc.py | 4 | ||||
-rw-r--r-- | qutebrowser/config/configfiles.py | 9 | ||||
-rw-r--r-- | qutebrowser/config/configinit.py | 11 | ||||
-rw-r--r-- | tests/unit/config/test_configexc.py | 6 | ||||
-rw-r--r-- | tests/unit/config/test_configinit.py | 18 |
6 files changed, 52 insertions, 6 deletions
diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index dd183a29c..a56a04694 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -27,6 +27,16 @@ Fixed deprecated and shows an error. Note that `:config-py-write` did write such invalid lines before v1.8.0, so existing config files might need adjustments. +- The `readability-js` userscript now handles encodings correctly (which it + didn't before for some websites). +- New `tabs.tooltips` setting which can be used to disable hover tooltips for + tabs. +- <Shift-Insert> can now be used to paste text starting with a hyphen. +- Following hints via the number keypad now works properly again. +- The logic for `:restart` has been revisited which should fix issues with + relative basedirs. +- Errors while reading the state file are now displayed instead of causing a + crash. v1.8.1 (2019-09-27) ------------------- diff --git a/qutebrowser/config/configexc.py b/qutebrowser/config/configexc.py index df171c365..d83ca403b 100644 --- a/qutebrowser/config/configexc.py +++ b/qutebrowser/config/configexc.py @@ -141,11 +141,13 @@ class ConfigFileErrors(Error): def __init__(self, basename: str, - errors: typing.Sequence[ConfigErrorDesc]) -> None: + errors: typing.Sequence[ConfigErrorDesc], *, + fatal: bool = False) -> None: super().__init__("Errors occurred while reading {}:\n{}".format( basename, '\n'.join(' {}'.format(e) for e in errors))) self.basename = basename self.errors = errors + self.fatal = fatal for err in errors: if err.traceback: log.config.debug("Config error stack:") diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py index f220d2ca4..df7fdaae1 100644 --- a/qutebrowser/config/configfiles.py +++ b/qutebrowser/config/configfiles.py @@ -55,7 +55,6 @@ class StateConfig(configparser.ConfigParser): super().__init__() self._filename = os.path.join(standarddir.data(), 'state') self.read(self._filename, encoding='utf-8') - qt_version = qVersion() # We handle this here, so we can avoid setting qt_version_changed if # the config is brand new, but can still set it when qt_version wasn't @@ -690,7 +689,13 @@ def saved_sys_properties() -> typing.Iterator[None]: def init() -> None: """Initialize config storage not related to the main config.""" global state - state = StateConfig() + + try: + state = StateConfig() + except configparser.Error as e: + msg = "While loading state file from {}".format(standarddir.data()) + desc = configexc.ConfigErrorDesc(msg, e) + raise configexc.ConfigFileErrors('state', [desc], fatal=True) # Set the QSettings path to something like # ~/.config/qutebrowser/qsettings/qutebrowser/qutebrowser.conf so it diff --git a/qutebrowser/config/configinit.py b/qutebrowser/config/configinit.py index 74c07e3ab..3a39e1bc3 100644 --- a/qutebrowser/config/configinit.py +++ b/qutebrowser/config/configinit.py @@ -60,6 +60,7 @@ def early_init(args: argparse.Namespace) -> None: objreg.register('config-commands', config_commands) config_file = standarddir.config_py() + global _init_errors try: if os.path.exists(config_file): @@ -68,10 +69,12 @@ def early_init(args: argparse.Namespace) -> None: configfiles.read_autoconfig() except configexc.ConfigFileErrors as e: log.config.exception("Error while loading {}".format(e.basename)) - global _init_errors _init_errors = e - configfiles.init() + try: + configfiles.init() + except configexc.ConfigFileErrors as e: + _init_errors = e for opt, val in args.temp_settings: try: @@ -149,6 +152,10 @@ def late_init(save_manager: savemanager.SaveManager) -> None: icon=QMessageBox.Warning, plain_text=False) errbox.exec_() + + if _init_errors.fatal: + sys.exit(usertypes.Exit.err_init) + _init_errors = None config.instance.init_save_manager(save_manager) diff --git a/tests/unit/config/test_configexc.py b/tests/unit/config/test_configexc.py index f3f86a6dd..0335d0cee 100644 --- a/tests/unit/config/test_configexc.py +++ b/tests/unit/config/test_configexc.py @@ -126,3 +126,9 @@ Fake traceback """) # Make sure the traceback is not indented assert '<pre>\nFake traceback\n' in html + + +def test_config_file_errors_fatal(): + err = configexc.ConfigErrorDesc("Text", Exception("Text")) + errors = configexc.ConfigFileErrors("state", [err], fatal=True) + assert errors.fatal diff --git a/tests/unit/config/test_configinit.py b/tests/unit/config/test_configinit.py index 93ca334ef..273c13d43 100644 --- a/tests/unit/config/test_configinit.py +++ b/tests/unit/config/test_configinit.py @@ -205,6 +205,12 @@ class TestEarlyInit: assert dump == '\n'.join(expected) + def test_state_init_errors(self, init_patch, args, data_tmpdir): + state_file = data_tmpdir / 'state' + state_file.write_binary(b'\x00') + configinit.early_init(args) + assert configinit._init_errors.errors + def test_invalid_change_filter(self, init_patch, args): config.change_filter('foobar') with pytest.raises(configexc.NoOptionError): @@ -325,16 +331,23 @@ class TestEarlyInit: configinit._init_envvars() -@pytest.mark.parametrize('errors', [True, False]) +@pytest.mark.parametrize('errors', [True, 'fatal', False]) def test_late_init(init_patch, monkeypatch, fake_save_manager, args, mocker, errors): configinit.early_init(args) + if errors: err = configexc.ConfigErrorDesc("Error text", Exception("Exception")) errs = configexc.ConfigFileErrors("config.py", [err]) + if errors == 'fatal': + errs.fatal = True + monkeypatch.setattr(configinit, '_init_errors', errs) + msgbox_mock = mocker.patch('qutebrowser.config.configinit.msgbox.msgbox', autospec=True) + exit_mock = mocker.patch('qutebrowser.config.configinit.sys.exit', + autospec=True) configinit.late_init(fake_save_manager) @@ -342,12 +355,15 @@ def test_late_init(init_patch, monkeypatch, fake_save_manager, args, 'state-config', unittest.mock.ANY) fake_save_manager.add_saveable.assert_any_call( 'yaml-config', unittest.mock.ANY, unittest.mock.ANY) + if errors: assert len(msgbox_mock.call_args_list) == 1 _call_posargs, call_kwargs = msgbox_mock.call_args_list[0] text = call_kwargs['text'].strip() assert text.startswith('Errors occurred while reading config.py:') assert '<b>Error text</b>: Exception' in text + + assert exit_mock.called == (errors == 'fatal') else: assert not msgbox_mock.called |