def test_format_exceptions(cgitb, as_html, monkeypatch): if cgitb: monkeypatch.setitem(sys.modules, 'IPython.core.ultratb', None) monkeypatch.setattr( exceptions, 'standard_metadata', lambda x: { 'package': 'test-package', 'version': '0.1.0' }, ) # we make sure to actually raise the exceptions, # otherwise they will miss the __traceback__ attributes. try: try: raise ValueError('cause') except ValueError as e: raise PluginError( 'some error', plugin_name='test_plugin', plugin="mock", cause=e, ) except PluginError: pass formatted = exceptions.format_exceptions('test_plugin', as_html=as_html) assert "some error" in formatted assert "version: 0.1.0" in formatted assert "plugin package: test-package" in formatted assert exceptions.format_exceptions('nonexistent', as_html=as_html) == ''
def format_exceptions(plugin_name: str, as_html: bool = False): """Return formatted tracebacks for all exceptions raised by plugin. Parameters ---------- plugin_name : str The name of a plugin for which to retrieve tracebacks. as_html : bool Whether to return the exception string as formatted html, defaults to False. Returns ------- str A formatted string with traceback information for every exception raised by ``plugin_name`` during this session. """ _plugin_errors = PluginError.get(plugin_name=plugin_name) if not _plugin_errors: return '' from napari import __version__ from ..utils._tracebacks import get_tb_formatter format_exc_info = get_tb_formatter() _linewidth = 80 _pad = (_linewidth - len(plugin_name) - 18) // 2 msg = [ trans._( "{pad} Errors for plugin '{plugin_name}' {pad}", deferred=True, pad='=' * _pad, plugin_name=plugin_name, ), '', f'{"napari version": >16}: {__version__}', ] err0 = _plugin_errors[0] if err0.plugin: package_meta = standard_metadata(err0.plugin) if package_meta: msg.extend([ f'{"plugin package": >16}: {package_meta["package"]}', f'{"version": >16}: {package_meta["version"]}', f'{"module": >16}: {err0.plugin}', ]) msg.append('') for n, err in enumerate(_plugin_errors): _pad = _linewidth - len(str(err)) - 10 msg += ['', f'ERROR #{n + 1}: {str(err)} {"-" * _pad}', ''] msg.append(format_exc_info(err.info(), as_html)) msg.append('=' * _linewidth) return ("<br>" if as_html else "\n").join(msg)
def test_error_reporter(qtbot, monkeypatch): """test that QtPluginErrReporter shows any instantiated PluginErrors.""" monkeypatch.setattr( qt_plugin_report, 'standard_metadata', lambda x: {'url': 'https://github.com/example/example'}, ) error_message = 'my special error' try: # we need to raise to make sure a __traceback__ is attached to the error. raise PluginError(error_message, plugin_name='test_plugin', plugin="mock") except PluginError: pass report_widget = qt_plugin_report.QtPluginErrReporter() qtbot.addWidget(report_widget) # the null option plus the one we created assert report_widget.plugin_combo.count() >= 2 # the message should appear somewhere in the text area report_widget.set_plugin('test_plugin') assert error_message in report_widget.text_area.toPlainText() # mock_webbrowser_open def mock_webbrowser_open(url, new=0): assert new == 2 assert "Errors for plugin 'test_plugin'" in url assert "Traceback from napari" in url monkeypatch.setattr(webbrowser, 'open', mock_webbrowser_open) qtbot.mouseClick(report_widget.github_button, Qt.LeftButton) # make sure we can copy traceback to clipboard report_widget.copyToClipboard() clipboard_text = QGuiApplication.clipboard().text() assert "Errors for plugin 'test_plugin'" in clipboard_text # plugins without errors raise an error with pytest.raises(ValueError): report_widget.set_plugin('non_existent') report_widget.set_plugin(None) assert not report_widget.text_area.toPlainText()
def test_getting_errors(invalid_entrypoint_plugin, caplog): with temp_path_additions(invalid_entrypoint_plugin): import invalid_entrypoint_plugin as mod try: raise ValueError('I caused this') except ValueError as e: err = PluginError(plugin=mod, plugin_name='invalid', cause=e) errs = PluginError.get(plugin=mod) assert mod in {p.plugin for p in errs} errs = PluginError.get(plugin_name='invalid') assert 'invalid' in {p.plugin_name for p in errs} assert 'I caused this' in err.format() err.log() assert ' Error in plugin "invalid"' in caplog.text
def test_format_exceptions(cgitb, as_html, monkeypatch): if cgitb: monkeypatch.setitem(sys.modules, 'IPython.core.ultratb', None) monkeypatch.setattr( exceptions, 'standard_metadata', lambda x: {'package': 'test-package', 'version': '0.1.0'}, ) _ = PluginError( 'some error', plugin_name='test_plugin', plugin="mock", cause=ValueError("cause"), ) formatted = exceptions.format_exceptions('test_plugin', as_html=as_html) assert "some error" in formatted assert "version: 0.1.0" in formatted assert "plugin package: test-package" in formatted assert exceptions.format_exceptions('nonexistent', as_html=as_html) == ''