diff --git a/clients/deluge.py b/clients/deluge.py
index 8918ec2b548b940a099d389d89a335dd13afabb4..3fb85cc1b3130ed5a9474f9ae5490ecee0a9c34d 100644
--- a/clients/deluge.py
+++ b/clients/deluge.py
@@ -21,7 +21,7 @@ class DelugeClient(TorrentClient):
         Add common headers needed to make the API requests
         :return: request
         """
-
+        # TODO pass this to parent
         self.send_log('Adding headers to request', 'debug')
 
         headers = {
@@ -47,13 +47,10 @@ class DelugeClient(TorrentClient):
 
         req = self._create_request(method='auth.check_session', params=[''])
 
-        try:
-            res = urlopen(req)
-        except URLError as e:
-            msg = 'Failed To check session state.  HTTP Error'
-            self.send_log(msg, 'error')
-            print(e)
-            return None
+        res = self._make_request(req, fail_msg='Failed To check session state.  HTTP Error')
+
+        if not res:
+            return
 
         result = self._process_response(res)
 
@@ -108,17 +105,10 @@ class DelugeClient(TorrentClient):
         :return: None
         """
         msg = 'Attempting to authenticate against {} API'.format(self.torrent_client)
-        self.send_log(msg, 'info')
 
         req = self._create_request(method='auth.login', params=[self.password])
 
-        try:
-            res = urlopen(req)
-        except URLError as e:
-            msg = 'Failed To Authenticate with torrent client.  HTTP Error. Aborting'
-            self.send_log(msg, 'critical')
-            print(e)
-            sys.exit(1)
+        res = self._make_request(req, genmsg=msg, fail_msg='Failed to contact API for authentication', abort_on_fail=True)
 
         output = self._process_response(res)
 
@@ -138,7 +128,6 @@ class DelugeClient(TorrentClient):
         msg = 'Successfully Authenticated With {} API'.format(self.torrent_client)
         self.send_log(msg, 'info')
 
-
     def _build_torrent_list(self, torrents):
         """
         Take the resulting torrent list and create a consistent structure shared through all clients
@@ -160,25 +149,26 @@ class DelugeClient(TorrentClient):
             self.torrent_list[hash]['tracker'] = data['tracker_host']
             self.torrent_list[hash]['total_files'] = data['num_files']
 
-
     def get_all_torrents(self):
         """
         Return a list of all torrents from the API
         :return:
         """
 
+        self.send_log('Getting list of torrents', 'debug')
+
         req = self._create_request(method='core.get_torrents_status', params=['',''])
-        try:
-            self._check_session() # Make sure we still have an active session
-            res = urlopen(req)
-        except URLError as e:
-            msg = 'Failed to get list of torrents.  HTTP Error'
-            self.send_log(msg, 'error')
-            print(e)
+
+        self._check_session() # Make sure we still have an active session
+
+        res = self._make_request(req, fail_msg='Failed to get list of torrents from API')
+
+        if not res:
             self.torrent_list = {}
             return
 
         output = self._process_response(res)
+
         if not output:
             return
 
diff --git a/clients/torrentclient.py b/clients/torrentclient.py
index 79926492391872555318a4c0c51c508b163b34e7..e6c42f87682871fd242e4e6e5d712db5bd155439 100644
--- a/clients/torrentclient.py
+++ b/clients/torrentclient.py
@@ -47,7 +47,7 @@ class TorrentClient:
         if not headers:
             return req
 
-        self.send_log('Adding headers to request', 'info')
+        self.send_log('Adding headers to request', 'debug')
         for k, v in headers.items():
             req.add_header(k, v)
 
@@ -62,6 +62,38 @@ class TorrentClient:
         """
         raise NotImplementedError
 
+    def _make_request(self, req, genmsg='', fail_msg='', abort_on_fail=None):
+        """
+        Make the web request.  Doing it here avoids a lot of duplicate exception handling
+        :param gen_msg: Message we can print to console or logs so we know about the request
+        :param fail_msg: Message we can print to console or logs on failure
+        :param abort_on_fail: Exit on failed request
+        :return: Response
+        """
+
+        if genmsg:
+            self.send_log(genmsg, 'info')
+
+        try:
+            res = urlopen(req)
+        except URLError as e:
+
+            if fail_msg:
+                msg = fail_msg
+            else:
+                msg = 'Failed to make request'
+
+            if abort_on_fail:
+                self.send_log(msg, 'critical')
+                self.send_log('Aborting', 'critical')
+                sys.exit(1)
+            else:
+                self.send_log(msg, 'error')
+
+            return None
+
+        return res
+
     def _process_response(self, res):
         # TODO May only be needed for deluge.  Remove from parent if that's the case
         raise NotImplementedError
diff --git a/clients/utorrent.py b/clients/utorrent.py
index d98f2bbd3f18817a06f181de050859092f545f8c..d20bf230bd658235d7faee21c8715e30b7a8e94f 100644
--- a/clients/utorrent.py
+++ b/clients/utorrent.py
@@ -96,14 +96,13 @@ class UTorrentClient(TorrentClient):
 
         req = self._create_request(params='action=getprops&hash={}'.format(hash))
 
-        try:
-            res = urlopen(req).read().decode('utf-8')
-        except URLError as e:
-            msg = 'Failed to get trackers from URL for hash {}'.format(hash)
-            self.send_log(msg, 'error')
+        fail_msg = msg = 'Failed to get trackers from URL for hash {}'.format(hash)
+        res = self._make_request(req, fail_msg=fail_msg)
+
+        if not res:
             return 'N/A'
 
-        res_json = json.loads(res)
+        res_json = self._process_response(res)
 
         tracker = res_json['props'][0]['trackers'].split()[0]
 
@@ -116,6 +115,13 @@ class UTorrentClient(TorrentClient):
 
         return tracker_url
 
+    def _process_response(self, res):
+
+        raw_output = res.read().decode('utf-8')
+        json_output = json.loads(raw_output)
+
+        return json_output
+
     def _get_file_count(self, hash):
         """
         Method for uTorrent to get total file since it requires another API call
@@ -128,16 +134,17 @@ class UTorrentClient(TorrentClient):
 
         req = self._create_request(params='action=getfiles&hash={}'.format(hash))
 
-        try:
-            res = urlopen(req).read().decode('utf-8')
-        except URLError as e:
-            msg = 'Failed to get file list from URL for hash {}'.format(hash)
-            self.send_log(msg, 'error')
+        res = self._make_request(req, fail_msg='Failed to get file list for hash '.format(hash))
+
+        if not res:
             return 'N/A'
 
-        res_json = json.loads(res)
+        output = self._process_response(res)
 
-        return len(res_json['files'][1])
+        if 'files' in output:
+            return len(output['files'][1])
+        else:
+            return 'N/A'
 
     def get_all_torrents(self):
         """
@@ -150,16 +157,15 @@ class UTorrentClient(TorrentClient):
 
         req = self._create_request(params='list=1')
 
-        try:
-            res = urlopen(req)
-            final = res.read().decode('utf-8')
-        except URLError as e:
-            msg = 'Failed to get list of all torrents'
-            print(e)
-            self.send_log(msg, 'error')
+        res = self._make_request(req, fail_msg='Failed to get list of all torrents')
+
+        if not res:
             self.torrent_list = {}
             return
 
-        final_json = json.loads(final)
+        output = self._process_response(res)
 
-        self._build_torrent_list(final_json['torrents'])
\ No newline at end of file
+        if 'torrents' in output:
+            self._build_torrent_list(output['torrents'])
+        else:
+            self.torrent_list = {}