Skip to content

Commit

Permalink
Merge pull request #7230 from ccordoba12/improve-report-issue
Browse files Browse the repository at this point in the history
PR: Use the error dialog to report issues too
  • Loading branch information
ccordoba12 authored May 30, 2018
2 parents 1b34cfa + c4d6dbc commit 5830348
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 87 deletions.
73 changes: 19 additions & 54 deletions spyder/app/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2365,34 +2365,6 @@ def render_issue(self, description='', traceback=''):
if versions['revision']:
revision = versions['revision']

# Store and format the reminder message for the troubleshooting guide
reminder_message_full = (
"<!--- **PLEASE READ:** Before submitting here, please carefully "
"consult our *Troubleshooting Guide*: {0!s} and search the "
"issues page for your error/problem, as most posted bugs are "
"duplicates or easy fixes.\n\n"
"If you don't find anything, please provide a detailed step-by-"
"step description (in English) of the problem and what led up to "
"it below. Issue reports without a clear way to reproduce them "
"will be closed. Thanks! --->"
).format(__trouble_url__)

reminder_message_short = (
"<!--- PLEASE READ: Complete the following checklist. "
"Issues without it may be closed. --->"
)

bug_checklist = (
"* [ ] Searched issues page for similar reports\n"
"* [ ] Read and followed relevant sections of the"
"[Troubleshooting Guide]({0!s})\n"
"* [ ] Reproduced after updating (`conda update spyder`)\n"
"* [ ] Tried basic troubleshooting\n"
" * [ ] Restarted Spyder\n"
" * [ ] Ran `spyder --reset`\n"
" * [ ] Reinstalled latest Anaconda\n"
).format(__trouble_url_short__)

# Make a description header in case no description is supplied
if not description:
description = "### What steps reproduce the problem?"
Expand All @@ -2403,13 +2375,9 @@ def render_issue(self, description='', traceback=''):
"```python-traceback\n"
"{}\n"
"```".format(traceback))
reminder_message = reminder_message_full
else:
error_section = ''
reminder_message = reminder_message_short + "\n\n" + bug_checklist
issue_template = """\
{reminder_message}
## Description
{description}
Expand All @@ -2429,8 +2397,7 @@ def render_issue(self, description='', traceback=''):
```
{dependencies}
```
""".format(reminder_message=reminder_message,
description=description,
""".format(description=description,
error_section=error_section,
spyder_version=versions['spyder'],
commit=revision,
Expand All @@ -2445,29 +2412,27 @@ def render_issue(self, description='', traceback=''):
return issue_template

@Slot()
def report_issue(self, body=None, title=None):
def report_issue(self, body=None, title=None, open_webpage=False):
"""Report a Spyder issue to github, generating body text if needed."""
if PY3:
from urllib.parse import quote
else:
from urllib import quote # analysis:ignore

if body is None:
body = self.render_issue()

url = QUrl(__project_url__ + '/issues/new')
if PYQT5:
from qtpy.QtCore import QUrlQuery
query = QUrlQuery()
query.addQueryItem("body", quote(body))
if title:
query.addQueryItem("title", quote(title))
url.setQuery(query)
from spyder.widgets.reporterror import SpyderErrorDialog
report_dlg = SpyderErrorDialog(self, is_report=True)
report_dlg.show()
else:
url.addEncodedQueryItem("body", quote(body))
if title:
url.addEncodedQueryItem("title", quote(title))
QDesktopServices.openUrl(url)
if open_webpage:
if PY3:
from urllib.parse import quote
else:
from urllib import quote # analysis:ignore
from qtpy.QtCore import QUrlQuery

url = QUrl(__project_url__ + '/issues/new')
query = QUrlQuery()
query.addQueryItem("body", quote(body))
if title:
query.addQueryItem("title", quote(title))
url.setQuery(query)
QDesktopServices.openUrl(url)

@Slot()
def trouble_guide(self):
Expand Down
25 changes: 7 additions & 18 deletions spyder/app/tests/test_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,7 @@ def test_issue_4066(main_window, qtbot):
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 0, timeout=EVAL_TIMEOUT)

# Close editor
ok_widget = obj_editor.bbox.button(obj_editor.bbox.Ok)
ok_widget = obj_editor.btn_close
qtbot.mouseClick(ok_widget, Qt.LeftButton)

# Wait for the segfault
Expand Down Expand Up @@ -1566,30 +1566,19 @@ def test_report_issue_url(monkeypatch):
attr_to_patch = ('spyder.app.mainwindow.QDesktopServices')
monkeypatch.setattr(attr_to_patch, MockQDesktopServices)

# Test when body=None, i.e. when Help > Report Issue is chosen
target_url = QUrl(target_url_base + '?body=' + body_autogenerated)
MainWindow.report_issue(mockMainWindow_instance, body=None, title=None)
assert MockQDesktopServices.openUrl.call_count == 1
MockQDesktopServices.openUrl.assert_called_once_with(target_url)

# Test with body=None and title != None
target_url = QUrl(target_url_base + '?body=' + body_autogenerated
+ "&title=" + title)
MainWindow.report_issue(mockMainWindow_instance, body=None, title=title)
assert MockQDesktopServices.openUrl.call_count == 2
mockQDesktopServices_instance.openUrl.called_with(target_url)

# Test when body != None, i.e. when auto-submitting error to Github
target_url = QUrl(target_url_base + '?body=' + body)
MainWindow.report_issue(mockMainWindow_instance, body=body, title=None)
assert MockQDesktopServices.openUrl.call_count == 3
MainWindow.report_issue(mockMainWindow_instance, body=body, title=None,
open_webpage=True)
assert MockQDesktopServices.openUrl.call_count == 1
mockQDesktopServices_instance.openUrl.called_with(target_url)

# Test when body != None and title != None
target_url = QUrl(target_url_base + '?body=' + body
+ "&title=" + title)
MainWindow.report_issue(mockMainWindow_instance, body=body, title=title)
assert MockQDesktopServices.openUrl.call_count == 4
MainWindow.report_issue(mockMainWindow_instance, body=body, title=title,
open_webpage=True)
assert MockQDesktopServices.openUrl.call_count == 2
mockQDesktopServices_instance.openUrl.called_with(target_url)


Expand Down
53 changes: 38 additions & 15 deletions spyder/widgets/reporterror.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

# Local imports
from spyder import __project_url__, __trouble_url__
from spyder.config.base import _
from spyder.config.base import _, DEV
from spyder.config.gui import get_font
from spyder.utils import icon_manager as ima
from spyder.utils.qthelpers import restore_keyevent
Expand Down Expand Up @@ -121,23 +121,32 @@ def __init__(self, parent=None):
class SpyderErrorDialog(QDialog):
"""Custom error dialog for error reporting."""

def __init__(self, parent=None):
def __init__(self, parent=None, is_report=False):
QDialog.__init__(self, parent)
self.is_report = is_report

self.setWindowTitle(_("Issue reporter"))
self.setModal(True)

# To save the traceback sent to the internal console
self.error_traceback = ""

# Dialog main label
if self.is_report:
title = _("Please fill the following information")
else:
title = _("Spyder has encountered an internal problem!")
main_label = QLabel(
_("""<h3>Spyder has encountered an internal problem!</h3>
Before reporting it, <i>please</i> consult our comprehensive
<b><a href=\"{0!s}\">Troubleshooting Guide</a></b>
which should help solve most issues, and search for
<b><a href=\"{1!s}\">known bugs</a></b> matching your error
message or problem description for a quicker solution.
""").format(__trouble_url__, __project_url__))
_("<h3>{title}</h3>"
"Before reporting this problem, <i>please</i> consult our "
"comprehensive "
"<b><a href=\"{trouble_url}\">Troubleshooting Guide</a></b> "
"which should help solve most issues, and search for "
"<b><a href=\"{project_url}\">known bugs</a></b> "
"matching your error message or problem description for a "
"quicker solution."
).format(title=title, trouble_url=__trouble_url__,
project_url=__project_url__))
main_label.setOpenExternalLinks(True)
main_label.setWordWrap(True)
main_label.setAlignment(Qt.AlignJustify)
Expand Down Expand Up @@ -184,6 +193,8 @@ def __init__(self, parent=None):
# Checkbox to dismiss future errors
self.dismiss_box = QCheckBox(_("Hide all future errors during this "
"session"))
if self.is_report:
self.dismiss_box.hide()

# Dialog buttons
gh_icon = ima.icon('github')
Expand All @@ -193,8 +204,12 @@ def __init__(self, parent=None):

self.details_btn = QPushButton(_('Show details'))
self.details_btn.clicked.connect(self._show_details)
if self.is_report:
self.details_btn.hide()

self.close_btn = QPushButton(_('Close'))
if self.is_report:
self.close_btn.clicked.connect(self.reject)

# Buttons layout
buttons_layout = QHBoxLayout()
Expand Down Expand Up @@ -231,8 +246,16 @@ def __init__(self, parent=None):

def _submit_to_github(self):
"""Action to take when pressing the submit button."""
# Get reference to the main window
if self.parent() is not None:
main = self.parent().main
if getattr(self.parent(), 'main', False):
# This covers the case when the dialog is attached
# to the internal console
main = self.parent().main
else:
# Else the dialog is attached to the main window
# directly
main = self.parent()
else:
main = None

Expand All @@ -249,11 +272,10 @@ def _submit_to_github(self):
issue_text = description

try:
if main is not None:
org = 'spyder-ide'
else:
# For testing
if DEV or main is None:
org = 'ccordoba12'
else:
org = 'spyder-ide'
github_backend = GithubBackend(org, 'spyder')
github_report = github_backend.send_report(title, issue_text)
if github_report:
Expand All @@ -274,7 +296,8 @@ def _submit_to_github(self):
" \n<!--- *** BEFORE SUBMITTING: PASTE CLIPBOARD HERE "
"TO COMPLETE YOUR REPORT *** ---!>\n")
if main is not None:
main.report_issue(body=issue_body, title=title)
main.report_issue(body=issue_body, title=title,
open_webpage=True)
else:
pass

Expand Down

0 comments on commit 5830348

Please sign in to comment.