Swift调用Firestore API时错误逃逸do-catch块问题咨询
问题解答
这是Firestore SDK的预期设计,具体原因和解决办法如下:
1. 空文档ID触发的是断言类错误,而非可捕获的Error
Firestore在创建DocumentReference时,会对传入的文档ID做合法性预校验——空字符串、包含/、\、#、$、[、]、*这些非法字符的ID都是不允许的。这类校验是通过**运行时断言(assertion)**或fatalError实现的,目的是在开发阶段直接暴露开发者的失误,而不是将其作为可恢复的错误抛出。
Swift的do-catch只能捕获通过throw关键字抛出的标准Error类型,断言或fatalError是直接终止程序执行,不会进入catch块。
2. 解决方案:提前校验文档ID合法性
在调用document(_:)之前,先手动校验ID的有效性,避免触发断言崩溃:
import FirebaseFirestore ... // 先校验item.id的合法性 guard let itemId = item.id, !itemId.isEmpty, !itemId.contains(where: { "/\\#$[]*".contains($0) }) else { Logger.firestore.error("无效的文档ID:\(item.id ?? "空值")") return } do { try db.collection(FBKeys.CollectionPath.users) .document(userID) .collection(Item.collectionName) .document(itemId) .setData(from: item) } catch { Logger.firestore.error("\(error.localizedDescription)") // 此时可正常捕获setData抛出的错误 }
补充说明
Debug模式下断言会直接崩溃,Release模式下部分断言可能被编译器优化跳过,但这不代表可以忽略ID校验——传入非法ID仍会导致Firestore操作失败,只是不会直接崩溃而已,所以提前校验才是正确的做法。
内容的提问来源于stack exchange,提问作者Paul B
相关产品推荐
相关产品推荐

