Repository: spyder-ide/spyder
Pull request: PR: Display an error message when Kite sends a non-dict response
<!--- Make sure to read the Contributing Guidelines:                   --->
<!--- https://github.com/spyder-ide/spyder/blob/master/CONTRIBUTING.md --->
<!--- and follow PEP 8, PEP 257 and Spyder's code style:               --->
<!--- https://github.com/spyder-ide/spyder/wiki/Dev:-Coding-Style      --->

## Description of Changes
This PR handles wrong Kite responses by displaying an error message and disabling Kite on Spyder 

![imagen](https://user-images.githubusercontent.com/1878982/94628782-8e3a7100-0286-11eb-8fcd-d397237b1d60.png)


* [ ] Wrote at least one-line docstrings (for any new functions)
* [ ] Added unit test(s) covering the changes (if testable)
<!--- Remember that an image/animation is worth a thousand words! --->
* [x] Included a screenshot or animation (if affecting the UI, see [Licecap](https://www.cockos.com/licecap/))


<!--- Explain what you've done and why --->




### Issue(s) Resolved

<!--- List the issue(s) below, in the form "Fixes #1234"; one per line --->

Fixes #13121


### Affirmation

By submitting this Pull Request or typing my (user)name below,
I affirm the [Developer Certificate of Origin](https://developercertificate.org)
with respect to all commits and content included in this PR,
and understand I am releasing the same under Spyder's MIT (Expat) license.

<!--- TYPE YOUR USER/NAME AFTER THE FOLLOWING: --->
I certify the above statement is true and correct: @andfoy 

<!--- Thanks for your help making Spyder better for everyone! --->


Problem statement:
TypeError: KiteClient.sig_response_ready in Kite's client
## Description

### What steps will reproduce the problem?

<!--- You can use Markdown here --->

I the procedures on the uninstall of kite through the terminal. Then I found the kite folders on my macbook and i send them to trash, but now my spider give me this issue report constantly. 

i tryed to open a new enviroment in anaconda but the problem persist.

Should I unistall and reinstall all spider?

Thx



### Traceback
```python-traceback
  File "/Users/xaf/opt/anaconda3/lib/python3.7/site-packages/spyder/plugins/completion/kite/client.py", line 173, in perform_request
    self.sig_response_ready.emit(req_id, response or {})
TypeError: KiteClient.sig_response_ready[int, dict].emit(): argument 2 has unexpected type 'str'
Traceback (most recent call last):
  File "/Users/xaf/opt/anaconda3/lib/python3.7/site-packages/spyder/plugins/completion/kite/client.py", line 173, in perform_request
    self.sig_response_ready.emit(req_id, response or {})
TypeError: KiteClient.sig_response_ready[int, dict].emit(): argument 2 has unexpected type 'str'
```

## Versions

* Spyder version: 4.1.3 
* Python version: 3.7.6
* Qt version: 5.9.6
* PyQt5 version: 5.9.2
* Operating System: Darwin 19.3.0

### Dependencies

```

# Mandatory:
applaunchservices >=0.1.7      :  0.2.1 (OK)
atomicwrites >=1.2.0           :  1.4.0 (OK)
chardet >=2.0.0                :  3.0.4 (OK)
cloudpickle >=0.5.0            :  1.4.1 (OK)
diff_match_patch >=20181111    :  20181111 (OK)
intervaltree                   :  None (OK)
IPython >=4.0                  :  7.13.0 (OK)
jedi =0.15.2                   :  0.15.2 (OK)
nbconvert >=4.0                :  5.6.1 (OK)
numpydoc >=0.6.0               :  1.0.0 (OK)
parso =0.5.2                   :  0.5.2 (OK)
pexpect >=4.4.0                :  4.8.0 (OK)
pickleshare >=0.4              :  0.7.5 (OK)
psutil >=5.3                   :  5.7.0 (OK)
pygments >=2.0                 :  2.6.1 (OK)
pylint >=0.25                  :  2.4.4 (OK)
pyls >=0.31.9;<0.32.0          :  0.31.10 (OK)
qdarkstyle >=2.8               :  2.8.1 (OK)
qtawesome >=0.5.7              :  0.7.2 (OK)
qtconsole >=4.6.0              :  4.7.4 (OK)
qtpy >=1.5.0                   :  1.9.0 (OK)
rtree >=0.8.3                  :  0.9.4 (OK)
sphinx >=0.6.6                 :  3.0.4 (OK)
spyder_kernels >=1.9.1;<1.10.0 :  1.9.1 (OK)
watchdog                       :  None (OK)
zmq >=17                       :  18.1.1 (OK)

# Optional:
cython >=0.21                  :  0.29.20 (OK)
matplotlib >=2.0.0             :  3.1.3 (OK)
numpy >=1.7                    :  1.18.1 (OK)
pandas >=0.13.1                :  1.0.4 (OK)
scipy >=0.17.0                 :  1.4.1 (OK)
sympy >=0.7.3                  :  1.5.1 (OK)
```

Hints from issue discussion:
@xavierricci, thanks for reporting. We're not really sure what to do about your problem.

@dalthviz, is there anything we could to prevent this?
I will need to check @ccordoba12.

Maybe for now @xavierricci , as a workaround, you could try to disable Kite from the preferences of Spyder? (if Spyder doesn't start check for the `spyder.ini` file which should be in `...\.spyder-py3\config` under your user, and change there the option `enable` under the `[kite]` section)
Note: After a quick check of the code, a validation could be added before emitting the signal as well as a message indicating that an unexpected result from Kite was received and you need to check your Kite installation (maybe we can add a link in that message to the Kite troubleshooting page or their link to contact support?).
Agreed, those are very good ideas @dalthviz!

Commit message: Improve message layout

Patch to review:
diff --git a/spyder/plugins/completion/kite/client.py b/spyder/plugins/completion/kite/client.py
index ac99d7c0bdd..39ee7f4b624 100644
--- a/spyder/plugins/completion/kite/client.py
+++ b/spyder/plugins/completion/kite/client.py
@@ -15,10 +15,12 @@
 
 # Third party imports
 from qtpy.QtCore import QObject, QThread, Signal, QMutex
+from qtpy.QtWidgets import QMessageBox
 import requests
 
 # Local imports
 from spyder.config.base import _
+from spyder.config.manager import CONF
 from spyder.plugins.completion.kite import KITE_ENDPOINTS, KITE_REQUEST_MAPPING
 from spyder.plugins.completion.kite.decorators import class_register
 from spyder.plugins.completion.kite.providers import KiteMethodProviderMixIn
@@ -170,4 +172,16 @@ def perform_request(self, req_id, method, params):
                 converter = getattr(self, converter_name)
                 if response is not None:
                     response = converter(response)
-        self.sig_response_ready.emit(req_id, response or {})
+        if not isinstance(response, dict):
+            QMessageBox.critical(
+                self, _('Kite error'),
+                _("The Kite completion engine returned an unexpected result "
+                  "for the request <tt>{0}</tt>: <br><br><tt>{1}</tt><br><br>"
+                  "Please make sure that your Kite installation is correct. "
+                  "In the meantime, Spyder will disable the Kite client to "
+                  "prevent further errors. For more information, please "
+                  "visit the <a href='https://help.kite.com/'>Kite help "
+                  "center</a>").format(method, response))
+            CONF.set('kite', 'enable', False)
+        else:
+            self.sig_response_ready.emit(req_id, response or {})


Code review comments:
diff_hunk: @@ -170,4 +172,16 @@ def perform_request(self, req_id, method, params):
                 converter = getattr(self, converter_name)
                 if response is not None:
                     response = converter(response)
-        self.sig_response_ready.emit(req_id, response or {})
+        if not isinstance(response, dict):
+            QMessageBox.critical(
+                self, _('Kite error'),
path: spyder/plugins/completion/kite/client.py
text: @user1:
I think that the `QMessageBox.critical` needs a `QWidget` as parent. Since the `KiteClient` is only a `QObject` maybe that's the reason why some test are failing? 

@user2:
I think to avoid this problem we should show the message only if `running_under_pytest()`  is False.