跳转至内容
There is a version suitable for your browser's language settings. Would you like to go to the english language of the site?
主页文档

失败处理

H1

在编写应用的过程中,我们常常面临两种失败情况。一种是与业务流程直接相关的失败,比如用户不存在或订单状态已经改变;另一种则是由意外错误引发的失败,例如网络问题或系统资源溢出。

针对业务相关的失败,我们可以使用 reject 方法主动抛出错误,为客户端提供明确的失败反馈。例如:

if (!user) throw reject("NOT_FOUND", undefined);

通过这种方式,我们能够精确地向客户端传达请求失败的原因,增强系统的健壮性和可靠性。调用者将接收到如下格式的响应:

{
"success": false,
"fail": {
"code": "NOT_FOUND",
"message": "Not Found",
"data": undefined
}
}

调用者可以通过 code.success 简易判断请求的成功与否,并通过 fail.code 识别具体的失败类型。这种设计有助于清晰地传达请求状态,便于调用者有效地处理和响应失败情况。

错误代码

/src/fail-code.ts 文件中,我们定义了所有可能的错误代码。

每个键都对应一个特定的错误代码,其值是一个函数,返回描述失败原因的字符串。这种设计便于管理和清晰地组织不同的错误代码,并为每个错误代码提供详细的说明。

/src/fail-code.ts
import type { MilkioFailCode } from "milkio";
export const failCode: MilkioFailCode = {
NETWORK_ERROR: () => "网络错误",
INTERNAL_SERVER_ERROR: () => "内部服务器错误",
NOT_FOUND: () => "未找到",
NOT_ALLOW_METHOD: () => "不允许的方法",
TYPE_SAFE_ERROR: (data) => `参数错误:当前值 '${data.value}' 不符合 '${data.expected}' 的要求`,
BUSINESS_FAIL: (data) => `${data}`,
// 可以在这里添加更多自定义的错误代码
// ...
};

参数传递

在调用 reject 方法时,可以通过参数调整向客户端发送的错误消息。这允许开发者根据需要灵活定制错误信息。

throw reject("ACCESS_EXCEEDED", { path: "/foo/bar", counter: 64 });

请记住,该方法仅接受一个参数。若需传递多个参数,请通过返回一个对象来实现,如下所示:

/src/fail-code.ts
export const failCode = {
ACCESS_EXCEEDED: (data: {path: string, counter: number}) => `访问过于频繁。路径 '${data.path}' 仅允许访问 ${data.counter} 次。`,
} satisfies MilkioFailCode;

这些参数也会被发送给客户端,以便进行进一步的处理。客户端将接收到如下格式的响应:

{
"success": false,
"fail": {
"code": "ACCESS_EXCEEDED",
"message": "访问过于频繁。路径 '/foo/bar' 仅允许访问 64 次。",
"data": { path: "/foo/bar", counter: 64 }
}
}

业务失败

大多数失败情况源于业务逻辑,例如超过了截止日期或库存不足。对于这些局部的业务失败,我们通常只需告知用户失败的原因。此时,我们可以统一使用 BUSINESS_FAIL 状态码:

throw reject("BUSINESS_FAIL", "活动尚未开始,凌晨 3 点开始抢购");

意料之外的错误

对于任何未被捕获的错误,客户端将接收到固定的 INTERNAL_SERVER_ERROR 错误码,以防止敏感信息泄露。

用户友好的失败信息

错误消息应向用户解释失败原因,但并非所有消息都足够用户友好。例如,密码长度不足导致的 TYPE_SAFE_ERROR 失败,我们可能不希望直接向用户显示:

参数错误:当前值为 '$input.user.password',不符合 'string & tags.MinLength<8>' 的要求。

而是希望用户看到更友好的提示:

密码太短啦,请尝试至少输入 8 个字符。

建议这种用户友好的错误消息处理在客户端完成。这样做的好处包括:

  • 实现前后端的彻底解耦。
  • 简化语言切换功能的实现,无需在客户端和服务器端都进行处理。
  • 确保客户端始终负责编写用户友好的失败消息。

详细信息请参考 Milkio Client