redis lua脚本中需用return "err xxx"返回错误,redis会将其转为resp错误类型;客户端如redis-py通过str(e)获取并解析json格式错误消息,注意转义、校验与统一约定。

Redis Lua脚本里怎么用 return 抛出可读错误?
Redis 的 Lua 环境不支持 error() 或 assert() 直接抛异常(会触发 ERR Error running script 且堆栈不可控),必须用 return 显式返回带 ERR 前缀的字符串,才能被客户端正确解析为错误响应。
关键点:Redis 会识别形如 "ERR xxx" 的返回值,并将其转为 RESP 错误类型(即以 - 开头的响应),客户端库(如 redis-py、jedis)会自动映射为对应语言的异常。
-
return "ERR missing key"→ 客户端收到redis.exceptions.RedisError: missing key -
return "ERR invalid type: "..type(val)→ 动态拼接,避免硬编码 - 不能写
return {err="xxx"}或return nil, "xxx"—— Redis 只认字符串前缀匹配
参数校验失败时,如何统一返回结构化错误?
常见误区是直接 return "ERR key not found",但实际业务中需要区分错误码、字段名、建议操作。可行做法是把元信息塞进错误字符串里,靠客户端解析(比如用 JSON 片段):
if not redis.call("EXISTS", KEYS[1]) then
return "ERR {\"code\":\"KEY_NOT_FOUND\",\"key\":\"" .. KEYS[1] .. "\"}"
end
这样客户端收到的是标准 RESP 错误,内容却是合法 JSON,方便上层提取结构化字段。注意双引号和嵌套引号要手动转义,Lua 字符串拼接较脆弱,建议只放必要字段。
Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
- 不要在错误消息里拼接用户输入(防注入),尤其
ARGV中的值需先string.match(v, "^%w+$")校验格式 - 避免长消息(Redis 对错误字符串长度无硬限制,但某些客户端或代理可能截断)
- 错误码建议全大写 + 下划线,和 HTTP status code 风格区分开
为什么 redis.call() 失败不会自动变成 Lua 错误?
这是最容易踩的坑:redis.call("HGET", "user:1", "age") 若 key 不存在,返回 nil,不是报错;只有命令语法错误(如少参数)、类型错误(对 string 执行 HGET)才会让 redis.call 抛出底层异常——但这个异常会被 Lua 层吞掉,最终还是变成不可控的 ERR Error running script。
- 所以所有业务校验必须显式做:
if not val then return "ERR field age missing" end - 用
redis.pcall()可捕获命令级错误(返回{ok=false, err="..."}),但代价是失去原子性保证(pcall内部失败不回滚已执行的call) - 推荐组合:先
call获取值,再 if 判空/类型,最后return "ERR ..."
在 redis-py 中怎么拿到自定义错误里的 JSON 字段?
redis-py 默认把 ERR xxx 转成 redis.exceptions.ResponseError,其 .args[0] 就是原始字符串。你需要手动解析:
try:
r.eval(script, 1, "user:999")
except redis.ResponseError as e:
msg = str(e)
if msg.startswith("ERR {"):
try:
err_data = json.loads(msg[4:]) # 去掉 "ERR "
code = err_data.get("code")
# 处理 KEY_NOT_FOUND...
except json.JSONDecodeError:
pass
注意:不要依赖 e.message(Python 3.12+ 已弃用),始终用 str(e);JSON 解析必须加 try,因为不是所有 ERR 都是 JSON 格式。
真正麻烦的不是怎么写 Lua,而是怎么让每个服务方都约定好错误格式、字段名、转义规则——一旦有人漏掉引号或拼错 key,下游解析就静默失败。










