Repository: rotki/rotki

Issue:
Rotki hangs when changing name of an API key
## Problem Definition

- Add an API key for an exchange e.g. Bitstamp and save
![image](https://user-images.githubusercontent.com/7383572/137938231-a113507a-82bb-439f-8d0c-55ea18ac440e.png)
- Delete the API key for Bitstamp
- Again add the API key for Bitstamp. Rotki will name it **Bitstamp 1** and save
- Edit the API key for the exchange and rename it to **Bistamp** removing the number **1**
- Rotki hangs and does not save

- Restart Rotki and it is able to save

## Logs



### System Description


Operating system: Linux
Rotki version: 1.21.2



Discussion:
Interesting. Will try to reproduce with the key you gave me and then with my kraken key to see if it's bitstamp only.
I reproduced. It's a frontend vue.js exception. Let's see if we can figure out why.
The exceptions:

```
<div role="treeitem" aria-expanded="true" tabindex="-1" style="box-sizing: border-box; min-width: 0px; min-height: 0px; flex: 0 0 auto; color: rgb(48, 57, 66); font-family: &quot;dejavu sans mono&quot;, monospace; font-size: 11px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(236, 241, 248); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><span class="source-code" style="box-sizing: border-box; min-width: 0px; min-height: 0px; font-family: var(--source-code-font-family); white-space: pre-wrap; font-size: var(--source-code-font-size)  !important; line-height: 1.2;"><span class="console-message-anchor" style="box-sizing: border-box; min-width: 0px; min-height: 0px; float: right; text-align: right; max-width: 100%; margin-left: 4px;"><span class="devtools-link" role="link" tabindex="-1" style="box-sizing: border-box; min-width: 0px; min-height: 0px; color: var(--color-text-secondary); text-decoration: underline; cursor: pointer; word-break: break-all;"><br class="Apple-interchange-newline">vue.runtime.esm.js:619</span> </span><span class="console-message-text" style="box-sizing: border-box; min-width: 0px; min-height: 0px; color: var(--override-error-text-color)  !important;">[Vue warn]: Error in v-on handler (Promise/async): "TypeError: Cannot read properties of undefined (reading 'trim')"

found in

---&gt; &lt;BigDialog&gt; at src/components/dialogs/BigDialog.vue
       &lt;ExchangeSettings&gt; at src/components/settings/api-keys/ExchangeSettings.vue
         &lt;VTabItem&gt;
           &lt;VTabsItems&gt;
             &lt;VTabs&gt;
               &lt;TabNavigation&gt; at src/components/helper/TabNavigation.vue
                 &lt;ApiKeys&gt; at src/views/settings/ApiKeys.vue
                   &lt;VMain&gt;
                     &lt;VApp&gt;
                       &lt;App&gt; at src/App.vue
                         &lt;Root&gt;</span></span></div><div class="" role="group" style="box-sizing: border-box; min-width: 0px; min-height: 0px; flex: 0 0 auto; color: rgb(48, 57, 66); font-family: &quot;dejavu sans mono&quot;, monospace; font-size: 11px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(236, 241, 248); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><span class="monospace" style="display: inline-block; --monospace-font-size: 11px; --monospace-font-family: dejavu sans mono, monospace; --source-code-font-size: 11px; --source-code-font-family: dejavu sans mono, monospace; box-sizing: border-box; min-width: 0px; min-height: 0px; font-family: var(--monospace-font-family); font-size: var(--monospace-font-size)  !important;">

  | warn | @ | vue.runtime.esm.js:619
-- | -- | -- | --
  | logError | @ | vue.runtime.esm.js:1893
  | globalHandleError | @ | vue.runtime.esm.js:1888
  | handleError | @ | vue.runtime.esm.js:1848
  | eval | @ | vue.runtime.esm.js:1865
  | Promise.catch (async) |   |  
  | invokeWithErrorHandling | @ | vue.runtime.esm.js:1865
  | invoker | @ | vue.runtime.esm.js:2188
  | invokeWithErrorHandling | @ | vue.runtime.esm.js:1863
  | Vue.$emit | @ | vue.runtime.esm.js:3903
  | emit | @ | Emit.js:30
  | emitter | @ | Emit.js:49
  | click | @ | generated-BigDialog.vue?7bfb:108
  | invokeWithErrorHandling | @ | vue.runtime.esm.js:1863
  | invoker | @ | vue.runtime.esm.js:2188
  | invokeWithErrorHandling | @ | vue.runtime.esm.js:1863
  | Vue.$emit | @ | vue.runtime.esm.js:3903
  | click | @ | VBtn.js:134
  | invokeWithErrorHandling | @ | vue.runtime.esm.js:1863
  | invoker | @ | vue.runtime.esm.js:2188
  | original._wrapper | @ | vue.runtime.esm.js:6961

</span></div>
```


and


```
TypeError: Cannot read properties of undefined (reading 'trim')
    at VueComponent._callee$ (ExchangeSettings.vue:205)
    at tryCatch (runtime.js:63)
    at Generator.invoke [as _invoke] (runtime.js:294)
    at Generator.eval [as next] (runtime.js:119)
    at asyncGeneratorStep (cjs.js?!../node_modules/babel-loader/lib/index.js!../node_modules/ts-loader/index.js?!../node_modules/cache-loader/dist/cjs.js?!../node_modules/vue-loader/lib/index.js?!./src/components/settings/api-keys/ExchangeSettings.vue?vue&type=script&lang=ts&:21)
    at _next (cjs.js?!../node_modules/babel-loader/lib/index.js!../node_modules/ts-loader/index.js?!../node_modules/cache-loader/dist/cjs.js?!../node_modules/vue-loader/lib/index.js?!./src/components/settings/api-keys/ExchangeSettings.vue?vue&type=script&lang=ts&:23)
    at eval (cjs.js?!../node_modules/babel-loader/lib/index.js!../node_modules/ts-loader/index.js?!../node_modules/cache-loader/dist/cjs.js?!../node_modules/vue-loader/lib/index.js?!./src/components/settings/api-keys/ExchangeSettings.vue?vue&type=script&lang=ts&:23)
    at new Promise (<anonymous>)
    at VueComponent.eval (cjs.js?!../node_modules/babel-loader/lib/index.js!../node_modules/ts-loader/index.js?!../node_modules/cache-loader/dist/cjs.js?!../node_modules/vue-loader/lib/index.js?!./src/components/settings/api-keys/ExchangeSettings.vue?vue&type=script&lang=ts&:23)
    at VueComponent.setup (ExchangeSettings.vue:121)
```

Resolving patch:
diff --git a/rotkehlchen/exchanges/binance.py b/rotkehlchen/exchanges/binance.py
--- a/rotkehlchen/exchanges/binance.py
+++ b/rotkehlchen/exchanges/binance.py
@@ -415,7 +415,11 @@ def api_query_dict(
     ) -> Dict:
         """May raise RemoteError and BinancePermissionError due to api_query"""
         result = self.api_query(api_type, method, options)
-        assert isinstance(result, Dict)  # pylint: disable=isinstance-second-argument-not-valid-type  # noqa: E501
+        if not isinstance(result, dict):
+            error_msg = f'Expected dict but did not get it in {self.name} api response.'
+            log.error(f'{error_msg}. Got: {result}')
+            raise RemoteError(error_msg)
+
         return result
 
     def api_query_list(
@@ -428,7 +432,12 @@ def api_query_list(
         result = self.api_query(api_type, method, options)
         if isinstance(result, Dict) and 'data' in result:
             result = result['data']
-        assert isinstance(result, List)  # pylint: disable=isinstance-second-argument-not-valid-type  # noqa: E501
+
+        if not isinstance(result, list):
+            error_msg = f'Expected list but did not get it in {self.name} api response.'
+            log.error(f'{error_msg}. Got: {result}')
+            raise RemoteError(error_msg)
+
         return result
 
     def _query_spot_balances(


Test patch: