Cloud Firestore异常未被except块捕获问题排查及代码分析
排查Firestore异常未被捕获的问题及解决办法
我来帮你分析代码里的问题,你遇到的except块无法捕获异常,主要有两个核心原因,咱们一步步拆解:
1. Try块的范围完全错了,异常根本不会在这里抛出
你当前的try块只包含了doc_ref = db.collection(u'tblAssgin').document(i)这行代码——但创建Firestore文档引用的操作本身不会抛出异常,哪怕这个文档实际不存在,Firestore也只会返回一个空的引用对象,不会报错。
真正可能抛出异常的是后面的doc_ref.get()操作:比如文档不存在、没有读取权限、网络连接失败等情况,才会触发Firestore的异常。但这行代码现在在else块里,不在try的覆盖范围内,所以except块自然抓不到任何错误。
2. 遍历列表时直接修改原列表的风险
你在遍历current_serving的同时执行current_serving.remove(doc_ref),这会导致列表的长度在遍历过程中变化,很容易出现索引错位、跳过元素甚至引发ValueError的问题(比如要移除的元素不在列表里)。
修正后的代码及说明
下面是调整后的代码,解决了这两个问题:
import datetime from threading import Timer import firebase_admin from firebase_admin import firestore import calendar db = firestore.Client() col_ref = db.collection(u'tblAssgin').get() current_serving = [doc.id for doc in col_ref] def sit_time(): # 遍历列表的副本,避免修改原列表干扰遍历流程 for doc_id in current_serving.copy(): try: doc_ref = db.collection(u'tblAssgin').document(doc_id) doc = doc_ref.get() # 主动检查文档是否存在,也可以直接依赖get()抛出的异常 if not doc.exists: raise firestore.exceptions.NotFound(f"文档 {doc_id} 不存在") # 处理assginTime字段(这里补全你原来的calendar相关逻辑) a = doc.get('assginTime') assign_time = datetime.datetime.fromtimestamp(calendar.timegm(a.timetuple())) # 这里添加你的后续业务逻辑 except firestore.exceptions.NotFound: # 精准捕获文档不存在的异常,移除对应的ID current_serving.remove(doc_id) except Exception as e: # 捕获其他所有意外异常,打印错误信息方便调试 print(f"处理文档 {doc_id} 时出错: {str(e)}")
关键修改点:
- 调整try块范围:把
doc_ref.get()和后续字段读取逻辑都放进try块,确保可能抛出异常的操作被覆盖 - 遍历列表副本:用
current_serving.copy()遍历,修改原列表不会影响遍历的完整性 - 精准捕获异常:优先捕获Firestore特定异常(比如
NotFound),再用通用Exception兜底,避免误吞无关错误 - 主动检查文档存在性:可以选择主动判断
doc.exists,也可以直接依赖get()抛出的异常,两种方式都可行
内容的提问来源于stack exchange,提问作者tanonymous22
相关产品推荐
相关产品推荐

