You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:23:16