Ejemplo n.º 1
0
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) == ''
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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
Ejemplo n.º 5
0
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) == ''