I use a python script to update ~500 Google Sheets (using some wrappers on the google api) every morning, and find that I need to catch API errors all the time. I wanted to write a generic "try this function, catch any errors" function, and was able to pass in the function and its parameters successfully, but it doesn't seem to catch the errors. Only if I wrap the original function call in a try/catch does it actually handle the error. This works, but it's starting to feel like half of my code is try/catch protocol.
Should this be working? Is there something different I can do so I only need to write my "try protocols" once?
My attempt at a generic catch function:
def try_function(function, teacher_name="teacher", note="unknown when", tab=None):
check = True
count = 0
while check:
check = False
try:
function
except Exception as e:
if str(e).find("Quota exceeded")>-1:
print("API Quota exceeded " + note + ", waiting 100 seconds - " + teacher_name)
time.sleep(100)
check = True
count+=1
elif str(e).find("The service is currently unavailable")>-1:
print("API threw 'currently unavailable error' " + note + ", waiting 100 seconds - " + teacher_name)
time.sleep(100)
check = True
count+=1
elif str(e).find("Read timed out.")>-1:
print("API threw 'Read timed out.' error " + note + ", waiting 150 seconds - " + teacher_name)
time.sleep(150)
check = True
count+=1
elif str(e).find("Internal error encountered.")>-1:
print("API threw 'Internal error encountered' " + note + ", waiting 100 seconds - " + teacher_name)
time.sleep(100)
check = True
count+=1
else:
print("Non-quota error " + note + ", teacher may not have been updated, waiting 250s - " + teacher_name)
print(e)
time.sleep(250)
del spread
continue
if count > 4:
print("Tried this 5 times, ending try loop - " + teacher_name)
del spread
continue
Called like this: try_function(spread.df_to_sheet(parameters), "name", "note")
Do I have to wrap that last line in order to actually catch an error?
spread.df_to_sheet(parameters)is the "API call", you can't do this literally as you want.spread.df_to_sheet(parameters)runs before your function is ever entered. You'd need macros to do this. You could change your function call totry_function(lambda: spread.df_to_sheet(parameters), "name", "note")to wrap the code in a 0-arity function (or you could usefunctools.partialfor this as well), then inside yourtry_functionfunction, you'd changetry: functiontotry: function(). That just delays the function being called until execution is inside thetryblock.lambda:+function()edit did what I needed. And the exceptions are mostly genericAPIErrors, with a couple exceptions, but I've edited my code to match that first and am dealing with their unique messages below.