Repository: Flexget/Flexget

Issue:
[Bug] Qbittorrent aborts instead of error when it receives invalid hash.
### Expected behaviour:


Qbitorrent plugin is recieving a torrent with no Hash. It should skip the torrent and continue to the next instead of completely aborting and not saving anything

### Actual behaviour:
2022-01-14 15:15:31 WARNING  qbittorrent   seriess         File with hash e49864aa67fc86748cb030d94 already in qbittorrent
2022-01-14 15:15:31 ERROR    qbittorrent   seriess         Error getting torrent info, invalid hash None
2022-01-14 15:15:31 CRITICAL plugin        seriess         Error when trying to send request to qBittorrent: Failed to add file to qBittorrent
2022-01-14 15:15:31 WARNING  task          seriess         Aborting task (plugin: qbittorrent)

As soon as it gets

### Steps to reproduce:
- Step 1: ... Have Qbitorrent a process a torrent with hash "None" through RSS.

  
#### Log:
2022-01-14 15:15:31 WARNING  qbittorrent   seriess         File with hash e49864aa67fc86748cb030d942ab already in qbittorrent
2022-01-14 15:15:31 ERROR    qbittorrent   seriess         Error getting torrent info, invalid hash None
2022-01-14 15:15:31 CRITICAL plugin        seriess         Error when trying to send request to qBittorrent: Failed to add file to qBittorrent
2022-01-14 15:15:31 WARNING  task          seriess         Aborting task (plugin: qbittorrent)
paste log output here
`


Discussion:
Looks like the self.check_torrent_exists returns a true/false but it's never taken into account by the function add_entries.
https://github.com/Flexget/Flexget/blob/develop/flexget/plugins/clients/qbittorrent.py#L279
Just continues regardless of check_torrent_exists status.
Can you run again  with debug logging and post here?
EDIT: And can you also update to the newest version first too, I've just added a couple more debug lines.

Resolving patch:
diff --git a/flexget/plugins/clients/qbittorrent.py b/flexget/plugins/clients/qbittorrent.py
--- a/flexget/plugins/clients/qbittorrent.py
+++ b/flexget/plugins/clients/qbittorrent.py
@@ -1,5 +1,4 @@
 import os
-from json import JSONDecodeError, loads
 
 from loguru import logger
 from requests import Session
@@ -71,11 +70,12 @@ def _request(self, method, url, msg_on_fail=None, **kwargs):
         try:
             response = self.session.request(method, url, **kwargs)
             if response.text == "Ok.":
-                return response
+                return True
             msg = msg_on_fail if msg_on_fail else f'Failure. URL: {url}, data: {kwargs}'
         except RequestException as e:
             msg = str(e)
-        raise plugin.PluginError(f'Error when trying to send request to qBittorrent: {msg}')
+        logger.error('Error when trying to send request to qBittorrent: {}', msg)
+        return False
 
     def check_api_version(self, msg_on_fail, verify=True):
         try:
@@ -116,13 +116,14 @@ def connect(self, config):
         self.check_api_version('Check API version failed.', verify=config['verify_cert'])
         if config.get('username') and config.get('password'):
             data = {'username': config['username'], 'password': config['password']}
-            self._request(
+            if not self._request(
                 'post',
                 self.url + self.api_url_login,
                 data=data,
                 msg_on_fail='Authentication failed.',
                 verify=config['verify_cert'],
-            )
+            ):
+                raise plugin.PluginError('Not connected.')
         logger.debug('Successfully connected to qBittorrent')
         self.connected = True
 
@@ -168,35 +169,41 @@ def check_torrent_exists(self, hash_torrent, verify_cert):
 
         return False
 
-    def add_torrent_file(self, file_path, data, verify_cert):
+    def add_torrent_file(self, entry, data, verify_cert):
+        file_path = entry['file']
         if not self.connected:
             raise plugin.PluginError('Not connected.')
 
         multipart_data = {k: (None, v) for k, v in data.items()}
         with open(file_path, 'rb') as f:
             multipart_data['torrents'] = f
-            self._request(
+            if not self._request(
                 'post',
                 self.url + self.api_url_upload,
                 msg_on_fail='Failed to add file to qBittorrent',
                 files=multipart_data,
                 verify=verify_cert,
-            )
+            ):
+                entry.fail(f'Error adding file `{file_path}` to qBittorrent')
+                return
         logger.debug('Added torrent file {} to qBittorrent', file_path)
 
-    def add_torrent_url(self, url, data, verify_cert):
+    def add_torrent_url(self, entry, data, verify_cert):
+        url = entry['url']
         if not self.connected:
             raise plugin.PluginError('Not connected.')
 
         data['urls'] = url
         multipart_data = {k: (None, v) for k, v in data.items()}
-        self._request(
+        if not self._request(
             'post',
             self.url + self.api_url_download,
             msg_on_fail=f'Failed to add url to qBittorrent: {url}',
             files=multipart_data,
             verify=verify_cert,
-        )
+        ):
+            entry.fail(f'Error adding url `{url}` to qBittorrent')
+            return
         logger.debug('Added url {} to qBittorrent', url)
 
     @staticmethod
@@ -290,9 +297,9 @@ def add_entries(self, task, config):
                     logger.debug('temp: {}', ', '.join(os.listdir(tmp_path)))
                     entry.fail("Downloaded temp file '%s' doesn't exist!?" % entry['file'])
                     continue
-                self.add_torrent_file(entry['file'], form_data, config['verify_cert'])
+                self.add_torrent_file(entry, form_data, config['verify_cert'])
             else:
-                self.add_torrent_url(entry['url'], form_data, config['verify_cert'])
+                self.add_torrent_url(entry, form_data, config['verify_cert'])
 
     @plugin.priority(120)
     def on_task_download(self, task, config):


Test patch: