跳转到内容

错误处理

带分类和重试元数据的结构化错误处理。全局 errors 表无需 require 即可使用。

-- 简单消息(类型默认为 UNKNOWN)
local err = errors.new("something went wrong")
-- 指定类型、可重试性和详情
local err = errors.new({
message = "user not found",
kind = errors.NOT_FOUND,
retryable = false,
details = {user_id = 123}
})

errors.new 接受字符串消息或至少包含 message 字段的表。不支持 (kind, message) 形式。

添加上下文同时保留类型、可重试性和详情:

local data, err = db.query("SELECT * FROM users")
if err then
return nil, errors.wrap(err, "failed to load users")
end
方法返回描述
err:kind()string错误类别
err:message()string错误消息
err:retryable()boolean/nil操作是否可重试
err:details()table/nil结构化元数据
err:stack()stringLua 堆栈跟踪
tostring(err)string完整表示
if errors.is(err, errors.INVALID) then
-- 处理无效输入
end
-- 或直接比较
if err:kind() == errors.NOT_FOUND then
-- 处理资源缺失
end
常量使用场景
errors.NOT_FOUND资源不存在
errors.ALREADY_EXISTS资源已存在
errors.INVALID错误的输入或参数
errors.PERMISSION_DENIED访问被拒绝
errors.UNAVAILABLE服务暂时不可用
errors.INTERNAL内部错误
errors.CANCELED操作已取消
errors.CONFLICT资源状态冲突
errors.TIMEOUT操作超时
errors.RATE_LIMITED请求过多
errors.UNKNOWN未指定错误

获取结构化调用栈:

local stack = errors.call_stack(err)
if stack then
print("Thread:", stack.thread)
for _, frame in ipairs(stack.frames) do
print(frame.source .. ":" .. frame.line, frame.name)
end
end
通常可重试不可重试
TIMEOUTINVALID
UNAVAILABLENOT_FOUND
RATE_LIMITEDPERMISSION_DENIED
ALREADY_EXISTS
if err:retryable() then
-- 可以安全重试
end
local err = errors.new({
message = "validation failed",
kind = errors.INVALID,
details = {
errors = {
{field = "email", message = "invalid format"},
{field = "age", message = "must be positive"}
}
}
})
local details = err:details()
for _, e in ipairs(details.errors) do
print(e.field, e.message)
end