错误处理
带分类和重试元数据的结构化错误处理。全局 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() | string | Lua 堆栈跟踪 |
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) endend| 通常可重试 | 不可重试 |
|---|---|
TIMEOUT | INVALID |
UNAVAILABLE | NOT_FOUND |
RATE_LIMITED | PERMISSION_DENIED |
ALREADY_EXISTS |
if err:retryable() then -- 可以安全重试endlocal 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