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

Golang Redis存储层Get方法如何正确返回EntityNotFound错误

Go 操作 Redis 区分「实体不存在」和「数据库错误」的实现方案

主流 Go Redis 客户端都已经内置了 key 不存在场景的专属错误常量,不需要自行匹配错误文本,直接通过标准库的错误判定方法即可精准区分两类场景。

核心实现逻辑(以社区主流 go-redis v8/v9 为例)

当执行GET命令查询不存在的 key 时,客户端会固定返回redis.Nil错误,你只需要用errors.Is对返回错误做判定即可,参考实现:

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/redis/go-redis/v9" // v8版本导入路径为"github.com/go-redis/redis/v8"
)

// 预定义业务层错误
var ErrEntityNotFound = errors.New("entity not found")
var ErrDBOperation = errors.New("db operation failed")

type EntityRepo struct {
	client *redis.Client
}

type Entity struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

func (r *EntityRepo) Get(ctx context.Context, entityID string) (*Entity, error) {
	key := fmt.Sprintf("entity:%s", entityID)
	val, err := r.client.Get(ctx, key).Result()
	if err != nil {
		// 优先判定key不存在场景
		if errors.Is(err, redis.Nil) {
			return nil, ErrEntityNotFound
		}
		// 其余错误统一归为数据库操作错误
		return nil, fmt.Errorf("%w: %v", ErrDBOperation, err)
	}

	// 反序列化拿到实体
	var e Entity
	if err := json.Unmarshal([]byte(val), &e); err != nil {
		return nil, fmt.Errorf("%w: unmarshal failed: %v", ErrDBOperation, err)
	}
	return &e, nil
}

其他客户端适配说明

如果你用的是老牌 Redigo 客户端,逻辑完全一致,只是对应的不存在错误常量为redis.ErrNil,判定代码片段如下:

// Redigo 客户端判定示例
conn := redisPool.Get()
defer conn.Close()

val, err := redis.Bytes(conn.Do("GET", key))
if err != nil {
	if errors.Is(err, redis.ErrNil) {
		return nil, ErrEntityNotFound
	}
	return nil, fmt.Errorf("%w: %v", ErrDBOperation, err)
}

注意事项

  • 禁止通过匹配错误文本(比如判断err.Error() == "redis: nil")的方式做判定,客户端版本迭代时错误文本可能变更,用官方暴露的错误常量才能保证向前兼容
  • 错误判定顺序不能颠倒:必须先判定key不存在的专属错误,再归类其他数据库错误,否则会把不存在场景误判为通用DB错误
  • 如果你使用的是其他二次封装的Redis ORM/工具类,直接查阅其文档中暴露的Nil/KeyNotFound类错误常量即可,判定逻辑完全相同

内容的提问来源于stack exchange,提问作者Umang Mundhra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:42:27