From 42a9dc489c1b90b5f685916ba686552b6741d1cc Mon Sep 17 00:00:00 2001
From: Tim Wilson <twilsonco@gmail.com>
Date: Sun, 20 Sep 2020 10:19:10 -0600
Subject: [PATCH] improved error handling

...kinda wish I had a proper background in python...
---
 bot.py | 47 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 40 insertions(+), 7 deletions(-)

diff --git a/bot.py b/bot.py
index 0b5c4b6..2deb42d 100644
--- a/bot.py
+++ b/bot.py
@@ -390,6 +390,8 @@ def make_client():
 	:return:
 	"""
 	global MAKE_CLIENT_FAILED
+	tsclient = None
+	lock()
 	try:
 		tsclient = TSClient(
 			TSCLIENT_CONFIG['host'],
@@ -398,10 +400,12 @@ def make_client():
 			password=TSCLIENT_CONFIG['password']
 		)
 		MAKE_CLIENT_FAILED = False
-		return tsclient
-	except:
+	except Exception as e:
+		logger.error("Failed to make TS client: {}".format(e))
 		MAKE_CLIENT_FAILED = True
-		return None
+	finally:
+		unlock()
+		return tsclient
 
 		
 def reload_client():
@@ -787,11 +791,27 @@ def prepare_notifications(changedTransfers, states=CONFIG['notification_states']
 						torrents[h] = t
 					
 					nameStr = d['name'].format(n, '' if n == 1 else 's')
-					valStr = ',\n'.join(["{}{}".format("**{}.**".format(i+1) if n > 1 else '', t['name'], "\n (error: *{}*)".format(t['errorString']) if t['errorString'] != "" else "") for i,t in enumerate(d['data'].values())])
+					vals = ["{}{}".format("**{}.**".format(i+1) if n > 1 else '', t['name'], "\n (error: *{}*)".format(t['errorString']) if t['errorString'] != "" else "") for i,t in enumerate(d['data'].values())]
+					valStr = ',\n'.join(vals)
 					
 					if len(embeds[-1]) + len(nameStr) + len(valStr) >= 6000:
 						embeds.append(discord.Embed(title=""))
 						embeds[-1].timestamp = ts
+					if len(nameStr) + len(valStr) > 1000:
+						valStr = ""
+						for i,v in enumerate(vals):
+							if len(embeds[-1]) + len(nameStr) + len(valStr) + len(v) >= 6000:
+								embeds.append(discord.Embed(title=""))
+								embeds[-1].timestamp = ts
+							if len(nameStr) + len(valStr) + len(v) > 1000:
+								embeds[-1].add_field(name=nStr, value=valStr, inline=False)
+								nameStr = ""
+								valStr = ""
+							else:
+								valStr += v
+								if i < len(vals) - 1:
+									valStr += ",\n"
+						pass
 				
 					embeds[-1].add_field(name=nameStr, value=valStr, inline=False)
 		return embeds, nTotal, torrents
@@ -916,7 +936,10 @@ async def run_notifications():
 async def loop_notifications():
 	while CONFIG['notification_enabled']:
 		# print("looping notifications")
-		await run_notifications()
+		try:
+			await run_notifications()
+		except Exception as e:
+			logger.error("Exception thrown in run_notifications: {}".format(e))
 		await asyncio.sleep(CONFIG['notification_freq'])
 	return
 	
@@ -951,7 +974,7 @@ async def on_ready():
 		await client.change_presence(activity=discord.Game("client load error!"))
 	else:
 		# client.loop.create_task(status_task())
-		await client.change_presence(activity=discord.Game("{}help".format(CONFIG['bot_prefix'])))
+		await client.change_presence(activity=discord.Game("Listening {}help".format(CONFIG['bot_prefix'])))
 		print('Logged in as ' + client.user.name)
 		print("Discord.py API version:", discord.__version__)
 		print("Python version:", platform.python_version())
@@ -1264,6 +1287,9 @@ async def summary(message, content="", repeat_msg_key=None):
 			except:
 				pass
 		
+		if TSCLIENT is None:
+			reload_client()
+		
 		stateEmojiFilterStartNum = 3 # the first emoji in stateEmoji that corresponds to a list filter
 		ignoreEmoji = ('āœ…')
 		
@@ -1596,7 +1622,8 @@ async def repeat_command(command, message, content="", msg_list=[]):
 			else:
 				try:
 					await msg['command'](message=msg['message'], content=msg['content'], repeat_msg_key=msg_key)
-				except:
+				except Exception as e:
+					logger.warning("Failed to execute repeat command {}(content={}): {}".format(msg['command'], msg['content'], e))
 					await asyncio.sleep(CONFIG['repeat_freq'])
 		else:
 			if msg['cancel_verbose']:
@@ -1634,6 +1661,9 @@ async def list_transfers(message, content="", repeat_msg_key=None):
 			except:
 				pass
 		
+		if TSCLIENT is None:
+			reload_client()
+		
 		torrents = TSCLIENT.get_torrents_by(sort_by=sort_by, filter_by=filter_by, filter_regex=filter_regex, id_list=id_list, num_results=num_results)
 		
 		embeds = torList(torrents, title="{} transfer{} matching '`{}`'".format(len(torrents),'' if len(torrents)==1 else 's',content))
@@ -1788,6 +1818,9 @@ async def modify(message, content=""):
 			except:
 				pass
 			
+			if TSCLIENT is None:
+				reload_client()
+			
 			if len(REPEAT_MSGS) == 0:
 				reload_client()
 			torrents = TSCLIENT.get_torrents_by(filter_by=filter_by, sort_by=sort_by, filter_regex=filter_regex, id_list=id_list, num_results=num_results)