Repository: spyder-ide/spyder

Issue:
Fancy exception handler does not show exception
At some point in the 3.x branch, a fancy exception handler was implemented which shows a window like ...

![screenshot_20170704_221613](https://user-images.githubusercontent.com/7941918/27842936-7055b228-6106-11e7-80ad-3c3b1f46fcb5.png)

when Spyder encounters the following exception (which I forced):

```
Traceback (most recent call last):
  File "/home/jitse/misc/spyder/spyder/plugins/ipythonconsole.py", line 955, in <lambda>
    kc.started_channels.connect(lambda c=client: self.process_started(c))
  File "/home/jitse/misc/spyder/spyder/plugins/ipythonconsole.py", line 1387, in process_started
    self.variableexplorer.add_shellwidget(client.shellwidget)
  File "/home/jitse/misc/spyder/spyder/plugins/variableexplorer.py", line 143, in add_shellwidget
    nsb = NamespaceBrowser(self)
  File "/home/jitse/misc/spyder/spyder/widgets/variableexplorer/namespacebrowser.py", line 65, in __init__
    QWdget.__init__(self, parent)
NameError: name 'QWdget' is not defined
```

The window only shows the traceback, not the exception itself (`NameError: name 'QWdget' is not defined`). As a consequence (I presume), when using the "Submit to GitHub" button, this information is also not included. I think this will rather complicate the debugging for us developers.

## Version and main components

* Spyder Version: 3.2.0.dev0 8dc91638
* Python Version: 3.6.1
* Qt Versions: 5.6.2, PyQt5 5.6 on Linux

## Dependencies
```
pyflakes >=0.6.0 :  1.5.0 (OK)
pycodestyle >=2.3:  2.3.1 (OK)
pygments >=2.0   :  2.1.3 (OK)
pandas >=0.13.1  :  0.19.2 (OK)
numpy >=1.7      :  1.12.1 (OK)
sphinx >=0.6.6   :  1.5.1 (OK)
rope >=0.9.4     :  0.9.4-1 (OK)
jedi >=0.9.0     :  0.9.0 (OK)
psutil >=0.3     :  5.0.1 (OK)
nbconvert >=4.0  :  4.2.0 (OK)
sympy >=0.7.3    :  1.0 (OK)
cython >=0.21    :  0.25.2 (OK)
qtconsole >=4.2.0:  4.2.1 (OK)
IPython >=4.0    :  5.1.0 (OK)
pylint >=0.25    :  1.6.4 (OK)

```



Discussion:
@jitseniesen, thanks for reporting. Nice to see you're helping us to test our fancy stuff :-)

@rlaverde, please take a look at this one. Hopefully It should be an easy fix :-) 

Resolving patch:
diff --git a/spyder/plugins/console.py b/spyder/plugins/console.py
--- a/spyder/plugins/console.py
+++ b/spyder/plugins/console.py
@@ -200,11 +200,15 @@ def register_plugin(self):
         self.focus_changed.connect(self.main.plugin_focus_changed)
         self.main.add_dockwidget(self)
         # Connecting the following signal once the dockwidget has been created:
-        self.shell.traceback_available.connect(self.traceback_available)
+        self.shell.exception_occurred.connect(self.exception_occurred)
     
-    def traceback_available(self, text):
-        """Traceback is available in the internal console: showing the 
-        internal console automatically to warn the user"""
+    def exception_occurred(self, text, is_traceback):
+        """Exception ocurred in the internal console.
+        Show a QMessageBox or the internal console to warn the user"""
+        # Skip errors without traceback
+        if not is_traceback and self.msgbox_traceback is None:
+            return
+
         if CONF.get('main', 'show_internal_console_if_traceback', False):
             self.dockwidget.show()
             self.dockwidget.raise_()
@@ -230,6 +234,14 @@ def traceback_available(self, text):
                 self.error_traceback = ""
                 self.msgbox_traceback.show()
                 self.msgbox_traceback.finished.connect(self.close_msg)
+                self.msgbox_traceback.setDetailedText(' ')
+
+                # open show details (iterate over all buttons and click it)
+                for button in self.msgbox_traceback.buttons():
+                    if (self.msgbox_traceback.buttonRole(button)
+                       == QMessageBox.ActionRole):
+                        button.click()
+                        break
 
             self.error_traceback += text
             self.msgbox_traceback.setDetailedText(self.error_traceback)
diff --git a/spyder/widgets/sourcecode/base.py b/spyder/widgets/sourcecode/base.py
--- a/spyder/widgets/sourcecode/base.py
+++ b/spyder/widgets/sourcecode/base.py
@@ -1270,7 +1270,7 @@ class ConsoleBaseWidget(TextEditBaseWidget):
     """Console base widget"""
     BRACE_MATCHING_SCOPE = ('sol', 'eol')
     COLOR_PATTERN = re.compile('\x01?\x1b\[(.*?)m\x02?')
-    traceback_available = Signal(str)
+    exception_occurred = Signal(str, bool)
     userListActivated = Signal(int, str)
     completion_widget_activated = Signal(str)
     
@@ -1391,8 +1391,7 @@ def append_text_to_shell(self, text, error, prompt):
                 else:
                     # Show error/warning messages in red
                     cursor.insertText(text, self.error_style.format)
-            if is_traceback:
-                self.traceback_available.emit(text)
+            self.exception_occurred.emit(text, is_traceback)
         elif prompt:
             # Show prompt in green
             insert_text_to(cursor, text, self.prompt_style.format)


Test patch: