症状
查询返回 record not found,调用方可能把它当作意外失败。GORM 在 First 与 Take 无匹配时返回 gorm.ErrRecordNotFound,且默认过滤软删除行。消息是准确的;问题在于对该调用点而言,缺失究竟是错误还是正常结果。
诊断
用 ToSQL 打印生成的语句确认过滤条件;缺失可接受时用 Find;检查软删除与 Unscoped。
db.ToSQL(func(tx *gorm.DB) *gorm.DB { return tx.Model(&User{}).Where("id = ?", id).First(&u) })
根因
ORM 报告 ErrRecordNotFound,因为经默认过滤与软删除过滤后没有行匹配,而调用方把它当作错误而非预期中的空结果。
修复
缺失有效时用 Find;用 errors.Is 与 gorm.ErrRecordNotFound 比较以区分未找到与真实失败;需要包含软删除行时用 Unscoped。应在各调用点明确语义而非一刀切处理。
验证
用已知缺失与已知存在两个值分别查询确认行为符合设计,并确认软删除行仅在使用 Unscoped 时出现。两种情形都正确才算处理妥当。
常见陷阱
把所有 record not found 都当故障返回 500 会把正常的空结果误报为服务错误。