将函数作为参数传递时捕获错误

Catch error when passing function as a parameter

我每天早上使用 python 脚本更新 ~500 Google 表格(在 google api 上使用一些包装器),发现我需要捕获 API 个错误 all 次。我想写一个通用的“试试这个函数,捕捉任何错误”的函数,并且能够成功地传入函数及其参数,但它似乎没有捕捉到错误。只有当我将原始函数调用包装在 try/catch 中时,它才会真正处理错误。这行得通,但开始感觉我的代码有一半是 try/catch 协议。

这应该有效吗?有什么不同的我可以做的,所以我只需要写一次我的“尝试协议”吗?

我对通用 catch 函数的尝试:

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

这样调用:try_function(spread.df_to_sheet(parameters), "name", "note")

我是否必须将最后一行换行才能真正捕获错误?

您需要在 try 块中实际调用该函数,并且您传入的内容必须是实际函数(而不是已经调用函数的结果)。为了使示例更简单,将异常处理简化为通用重试(请注意,在现实生活中,您通常会通过匹配异常类型而不是尝试解析其字符串表示来处理不同类型的异常),它看起来像这样:

def try_function(function, teacher_name="teacher", note="unknown when"):
    count = 0
    while True:
        try:
            function()
            return
        except Exception as e:
            print(f"Error: {e} ({note}), waiting 100s and retrying...")
            count += 1
            time.sleep(100)
        if count > 4:
            print(f"Tried this 5 times, ending try loop - {teacher_name}")
            return

try_function(lambda: spread.df_to_sheet(parameters), "name", "note")

请注意,lambda 表达式创建了一个不带参数的函数,该函数将在调用时调用 spread.df_to_sheet(这将发生在您的 try 块中)。这和写一样:

def to_sheet_fn():
    spread.df_to_sheet(parameters)

try_function(to_sheet_fn, "name", "note")