Gorm RaiseErrorOnNotFound不生效,无记录时未返回ErrRecordNotFound
问题原因
Gorm的Find方法用于查询多条记录,即便结果为空(返回空切片),它也不会返回gorm.ErrRecordNotFound——这个错误仅在First/Last/Take这类查询单条记录但未找到匹配项的场景下才会触发。你设置RaiseErrorOnNotFound = true无效的原因是:每次调用r.Get(ctx)都会生成新的DB实例,之前的配置不会作用到后续查询,且Find本身不支持该触发逻辑。
解决方案
方法1:手动检查结果长度
直接判断返回的切片是否为空,为空则返回目标错误:
func (r *MatchesRepository) GetLeagueIds(ctx context.Context, userID int) ([]int, error) { var leagueIDs []int err := r.Get(ctx).Model(&model.Match{}). Where("uid = ?", userID).Select("league_id").Find(&leagueIDs).Error if err != nil { return leagueIDs, err } // 无匹配记录时返回指定错误 if len(leagueIDs) == 0 { return leagueIDs, gorm.ErrRecordNotFound // 也可返回自定义错误:return leagueIDs, errors.New("Record not found") } return leagueIDs, nil }
方法2:先校验记录数量(可选)
如果需要先确认记录存在性再执行查询,可先通过Count统计:
func (r *MatchesRepository) GetLeagueIds(ctx context.Context, userID int) ([]int, error) { var count int64 err := r.Get(ctx).Model(&model.Match{}).Where("uid = ?", userID).Count(&count).Error if err != nil { return nil, err } if count == 0 { return nil, gorm.ErrRecordNotFound } var leagueIDs []int err = r.Get(ctx).Model(&model.Match{}).Where("uid = ?", userID).Select("league_id").Find(&leagueIDs).Error return leagueIDs, err }
额外提示
- 尽量保持DB实例链式调用,避免重复调用
r.Get(ctx)生成新实例 Where使用占位符?比map参数更高效,也能避免潜在的SQL注入风险
内容的提问来源于stack exchange,提问作者vishal
相关产品推荐
相关产品推荐

