应使用 redis.error_reply() 而非裸 error(),因其生成标准 ERR 响应、带统一前缀、支持结构化字段(如 code/message/trace_id),便于客户端解析与排查;裸 error() 易混淆、难扩展、可能被静默吞掉。

直接用 redis.error_reply(),别写裸 error()。它生成标准 ERR 响应,客户端能原样收到带前缀的错误字符串,且结构可控;裸 error() 虽然也能传回,但内容松散、难解析、易和网络层错误混淆。
为什么不能只用 error("xxx")
Redis 会把 error() 的参数原样包进 ERR 响应体返回,比如 error("key not found") → 客户端收到 (error) key not found。问题在于:
– 没有统一前缀,和 Redis 自身报错(如 (error) ERR Operation against a key holding the wrong kind of value)混在一起,客户端靠字符串匹配判断类型极不可靠;
– 无法嵌入上下文字段(如错误码、trace_id),后续排查困难;
– 某些客户端库(尤其带重试逻辑的)会把无 ERR 前缀的响应当成非脚本错误静默吞掉。
redis.error_reply() 怎么用才有效
它接受一个字符串或 Lua 表作为参数。传表时,Redis 不解析,但你可约定 JSON 格式,方便客户端解析:
return redis.error_reply({
code = "INVALID_ARG",
message = "ARGV[1] must be a positive integer",
trace_id = "trc_abc123"
})
最终返回给客户端的是:(error) {"code":"INVALID_ARG","message":"ARGV[1] must be a positive integer","trace_id":"trc_abc123"}。
注意:
– 必须 return,不能只调用;
– 表里字段名随意,但建议固定(如 code/message),避免客户端每次都要适配;
– 不要传嵌套太深的表,Redis 不校验,但客户端解析成本上升。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
错误捕获必须配合 redis.pcall() 使用
redis.call() 一出错就终止脚本,根本没机会调 redis.error_reply();只有 redis.pcall() 能把错误兜住,让你决定是否自定义返回:
- 用
redis.pcall("GET", KEYS[1])替代redis.call("GET", KEYS[1]) - 检查返回值:
local ok, res = redis.pcall("HGET", KEYS[1], ARGV[1]) - 若
not ok,说明命令失败,此时再构造redis.error_reply()返回
常见漏点:只对 redis 命令用 pcall,却忘了对 Lua 层逻辑(比如 tonumber(ARGV[1]) == nil)做校验——这类错误仍会触发裸 error(),必须手动 if 拦截。
真正难的不是写 redis.error_reply(),而是让所有可能出错的路径(redis 命令失败、参数非法、业务规则不满足)都走到同一个错误出口,而不是散落在各处用不同方式抛错。

















