@gainratio/errors

中文文档
0.4.0发布于 2026/10/26MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 4185

给出您的 JavaScript 或 TypeScript app 中的每一个错误 , 一个固定代码和一个清晰的消息, 每个屏幕都一样 .

中文使用文档
文档目录10 节
  1. 试试看
  2. 在用户语言中显示错误
  3. 如何运作
  4. 从哪一个代码列表开始
  5. 它不会做的
  6. 什么时候用别的东西
  7. 安装
  8. 开发
  9. 详细情况
  10. 许可证

@ reconratio/ 错误

给出您的 JavaScript 或 TypeScript app 中的每一个错误 , 一个固定代码和一个清晰的消息, 每个屏幕都一样 .

npm install @gainratio/errors (节点22.13或更新,无属地.

CI npm License: MIT

在大多数应用中,每个 catch 块写入它自己的错误消息, 所以有一个问题 以几种不同方式出现. 一个人工智能供应商说"402必须付款", 一个屏幕上写着"没有信用" 而另一个屏幕上写着"检查你的模型" 设置". 您的日志使用第三个措辞, 您的 API 发送第四个 。 没有人可以 搜索日志以查找一个失败,用户会被告知错误的事情.

这个软件包提供了您整个应用程序的错误代码列表 。 你给我 无论失败( HTTP 状态、 抛出错误、 网络掉落) 它都会给出 返回一个代码,例如 ai.provider.out_of_credits,一个句子一个人可以 读取,与标准 JSON 机构相同的错误 您的 API 可以发送. 每种语言的代码都是一样的. 句子来自用户的 西班牙语和葡萄牙语译文 每个内置的密码船 与包裹. 它不记录、重试或报告错误。 你的应用仍然决定如何处理他们.

技术文件: 建筑 • 妇女 API 指南 • 妇女 开始开发者

试试看

  1. 制作空项目并安装软件包 :

    mkdir try-errors && cd try-errors && npm init -y >/dev/null && npm install @gainratio/errors
    
  2. 另存为 try.mjs (这是 examples/try.mjs:

import { aiPack, corePack, defineErrorsWith } from "@gainratio/errors";

// Your app's list of error codes: 10 everyday ones + 9 for calling an AI service.
// Both lists claim some statuses (401, 404, 429, 5xx, timeouts). The list you
// pass first wins those, so here a 429 is http.rate_limited, not the ai.* code.
const errors = defineErrorsWith({}, corePack, aiPack);

// Four raw failures, the way they actually reach a catch block.
const failures = [
  { status: 402 }, // fetch() got "402 Payment Required"
  { status: 429 }, // fetch() got "429 Too Many Requests"
  new TypeError("Failed to fetch"), // the network dropped
  { status: 418, message: "I'm a teapot" }, // something nobody planned for
];

for (const raw of failures) {
  const code = errors.classify(raw);
  console.log(code.padEnd(28), errors.describe(code));
}

// The same error as a JSON body your API can send back.
const body = errors.toProblemDetails("ai.provider.out_of_credits");
console.log(JSON.stringify(body));

// An Error you can throw. Its .message is the code, so logs stay searchable.
// The sentence comes from describe().
// Starting from a raw failure, problemFor() classifies it and keeps the
// observed status — including when the matched code registers several.
const fromRaw = errors.problemFor({ status: 422 });
console.log(JSON.stringify(fromRaw));

const err = errors.create("config.missing", { field: "API_KEY" });
console.log(err.message);
console.log(errors.describe(err.code, err.params));
  1. 运行 node try.mjs。这是此代码中的真正输出 仓库 :
ai.provider.out_of_credits   Your provider account is out of credits. Add credits and try again.
http.rate_limited            Too many requests. Wait a moment and try again.
net.unreachable              Couldn't reach the server. Check your connection and try again.
internal.unknown             Something went wrong. Try again.
{"type":"ai.provider.out_of_credits","title":"Your provider account is out of credits. Add credits and try again.","status":402}
{"type":"internal.unknown","title":"Something went wrong. Try again.","status":422}
config.missing
A required setting is missing: API_KEY.

每次失败都有一个代码和一个句子. 这429去 corePack是因为 http.rate_limited 因为 corePack 首先列出(参见 从哪一个代码列表开始) (中文(简体) ). 这个 茶壶没有匹配,所以它掉回 internal.unknown 而不是显示 原始错误。 JSON行是网络API的标准出错格式(RFC 9457,, "问题细节",准备从服务器发送.

后两行是您可以读取的错误 throw。 。 .message 是密码 (单位:千美元)config.missing),不是句子,所以同样的失败总是记录同样的 可搜索文本。 为了显示句子,呼叫 errors.describe(err.code, err.params)。 。 。 .

要用另一种语言显示句子,见下一节.

在用户语言中显示错误

describe 以您的应用程序的翻译功能作为第三个参数 。 它问 键 errors.<code> (例如 errors.http.rate_limited) (中文(简体) ). 狦 翻译有那个密钥,用户看到了. 如果不是,他们就会看到英国人 从代码列表中的句子,从不带生键。 代码本身从未 更改,所以在每种语言中,您的日志和API保持不变.

包裹船西班牙号(es)和巴西葡萄牙语(pt) 全部24项 内置代码,作为 plain i18next JSON 文件. 把它们装入你旁边的i18 已经使用 :

npm install @gainratio/errors i18next

另存为 languages.mjs (这是 examples/languages.mjs运行 node languages.mjs数字 :

import { corePack, defineErrorsWith } from "@gainratio/errors";
import es from "@gainratio/errors/locales/es.json" with { type: "json" };
import pt from "@gainratio/errors/locales/pt.json" with { type: "json" };
import i18next from "i18next";

const errors = defineErrorsWith({}, corePack);

// Load the Spanish and Portuguese files that ship with the package into your
// own i18next. English needs no file: it comes from the list of codes.
await i18next.init({
  fallbackLng: "en",
  // describe() returns plain text, like its English. Escape it where you
  // render it, not here, or "/" comes back as "&#x2F;".
  interpolation: { escapeValue: false },
  resources: { es: { translation: es }, pt: { translation: pt } },
});

const code = errors.classify({ status: 429 }); // always "http.rate_limited"

for (const language of ["en", "es", "pt-BR", "fr"]) {
  const t = i18next.getFixedT(language);
  console.log(language.padEnd(6), errors.describe(code, {}, t));
}

// Values fill in the same way in every language.
const t = i18next.getFixedT("es");
console.log(
  errors.describe("config.missing", { field: "Settings / AI key" }, t),
);

// On the wire, only the title changes. The code and type never do.
const body = errors.toProblemDetails(
  code,
  {},
  { title: errors.describe(code, {}, t) },
);
console.log(JSON.stringify(body));

实际输出 :

en     Too many requests. Wait a moment and try again.
es     Demasiadas solicitudes. Espera un momento e inténtalo de nuevo.
pt-BR  Muitas solicitações. Aguarde um momento e tente de novo.
fr     Too many requests. Wait a moment and try again.
Falta un ajuste obligatorio: Settings / AI key.
{"type":"http.rate_limited","title":"Demasiadas solicitudes. Espera un momento e inténtalo de nuevo.","status":429}

i18next进行语言匹配. pt-BR (和 pt-PT得到葡萄牙语 文件,以及没有文件的语言,例如 fr获得英语。 保留 escapeValue: false数字 : describe 返回纯文本,与其英文相同, 然后从你制造的地方逃出 随着i18next的默认值,一个像 Settings / AI key 回来作为 Settings &#x2F; AI key。包裹从不选择 语言本身,从不导入 i18next。 形状为 t(key, params) 在它的位置工作。 对于自己的代码,添加 errors.<code> 用于您自己的翻译文件的密钥, 或设置 i18nKey 重用密钥的条目 你已经有了。 这个 API 指南 有细节.

如何运作

flowchart LR
    A["Raw failure<br/>(402, timeout, network down)"] --> B["classify()<br/>rules from YOUR catalog"]
    B --> C["One stable code<br/>ai.provider.out_of_credits"]
    C --> D["describe()<br/>a sentence, in your language"]
    C --> E["toProblemDetails()<br/>RFC 9457 JSON"]

应用程序启动时, 您会创建一个代码列表 。 每个代码都有一个类别,一个 英文句子,以及"HTTP station 402"等可选的标注规则 或者"错误消息提到超时". classify 看看你的失败 传入( 输入) status页:1 name,并只运行规则 您的列表,所以它返回一个代码 从列表中. describe 将代码变为 句子,和 toProblemDetails 把它变成JSON的身体。 没有隐藏 全局列表,没有网络或文件访问。 逻辑大约为260行TypeScript.

从哪一个代码列表开始

货包船4个现成名单. 它们是可选的。 您也可以写 每一个代码你自己.

列表代码用它当
corePack10个几乎总是。 每天HTTP出错的代码,网络故障,超时,以及不良的配置.
aiPack第9条你的应用程序叫AI模型提供者:没有键,坏键,出自信用,利率有限.
bundlePack页:1您的应用程序下载并检查设备上的文件, 如模型或数据集 .
starterPack第 18 条仅供已经使用过的更老的应用程序使用. 新代码应当使用 corePack。 。 。 .

starterPack 为较早的呼叫者保留被冻结; 新呼叫者应选择 corePack, (中文(简体) ), aiPack,或 bundlePack。 。 。 .

列表组合:您通过的每一列表的每个代码都会被注册. 如果两个名单 定义相同的代码,您得到一个 DuplicateCodeError 当应用程序启动时,永远不会 寂静胜相. 只有在两个不同的代码声称相同时才有秩序 状态。 在上述例子中, corePack 首先,所以429会变成 http.rate_limited 只有402个到达 aiPack。如果仅登记 处理给 AI 提供者的电话, put aiPack 首先,一个429成为 ai.provider.rate_limited编辑 建筑 医生列表 两种情况都一样.

aiPack 没有包罗万象的密码 所以 defineErrorsWith({}, aiPack) 独自一人 扔出并告诉你添加 corePack 或者从你的密码中选择一个 fallbackCode。 。 。 .

它不会做的

  • 它不记录、重试或报告错误,也不发送任何东西 随便哪里 与您的日志或错误跟踪器对等 .
  • 无法猜测只有你的应用程序知道的原因 。 添加带有规则的代码 对于它.
  • 它不会为 HTML 逃避消息 。 离开你制造它们的地方 数值 所以永远不要通过 暗号.
  • 它只在节点测试。 它没有节点的进口, 所以捆绑机可以运送 到浏览器, 但是没有浏览器测试在 CI 中运行 .
  • 这是前1.0。 代号被视为稳定合同 但API可以 仍然在小版本之间变化。 见 变化。 。 。 .

什么时候用别的东西

如果你需要的话使用
一个小应用程序中的一两个错误屏幕几个手写口信. 这太过分了.
只有文本的 HTTP 状态, 一种语言一个小 switch (status) 帮助者
收集错误、警报和仪表板哨兵等错误追踪器. 它与这个配对: 登录这个软件包给你的代码 .
您的屏幕、 日志和 API 回复共享的一组错误代码@gainratio/errors

安装

npm install @gainratio/errors    # or: pnpm add @gainratio/errors

它需要节点22.13或更新而无依赖性. 没有什么 配置 。 唯一的设置是当没有匹配时返回哪个代码(参见 页:1 API 指南) (中文(简体) ).

开发

git clone https://github.com/gainratio/errors.git && cd errors
corepack enable && pnpm install
pnpm gate

pnpm gate 运行 lint、 类型检查、 100%覆盖栏的测试以及 建设。 同样的指令CI运行,需要不到20秒。 开始 开始开发者,覆盖节点 要使用的版本,代码的映射,以及第一次修改的行走.

详细情况

  • 建筑问:如何 classify 选择一个代码,四个 名单,JSON机构的安全规则, 安全模型, 测试证明.
  • API 指南: 每一个导出, 包含您自己的代码的示例, 翻译,自定义后退,并扔出一个被编码的错误.
  • 开始开发者: 从新克隆 到一个经过的建筑物 和你的第一个变化.
  • 交互式架构映射: 相同的设计 作为可点击的图表.
  • 实例数字 : try.mjs 财务报告和审定财务报表 languages.mjs (上文), out-of-credits.mjs,以及 quickstart.mjs,它添加了您的代码和一个 西班牙语译名.
  • 警卫:威胁模型和如何报告出问题.
  • 捐款额:更改的规则.
  • 变化:每个版本的变化.

许可证

麻省理工学院. 见 自由主义。 。 。 .

版本与发布记录

@gainratio/errors 共发布 5 个版本,首次发布于 2026/10/02;过去 12 个月发布了 5 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.4.0latest2026/10/2621 天前
0.3.12026/10/161 个月前
0.3.02026/10/161 个月前
0.2.12026/10/031 个月前
0.0.0-bootstrap.0bootstrap2026/10/021 个月前

关于 @gainratio/errors 的常见问题

@gainratio/errors 是什么?

给出您的 JavaScript 或 TypeScript app 中的每一个错误 , 一个固定代码和一个清晰的消息, 每个屏幕都一样 .

如何安装 @gainratio/errors?

在项目目录运行 npm install @gainratio/errors,或使用 pnpm add / yarn add / bun add。

@gainratio/errors 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@gainratio/errors 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@gainratio/errors 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.13。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@gainratio/errors 可以商用吗?

@gainratio/errors 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@gainratio/errors 的下载量有多少?

根据 npm 官方下载统计,@gainratio/errors 在 2026/10/16 – 2026/11/14 这 30 天内被下载 4,185 次,日均约 140 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@gainratio/errors 还在维护吗?

最新版本 0.4.0 发布于 2026/10/26(21 天前);至今共发布 5 个版本,其中过去 12 个月发布了 5 个;首次发布于 2026/10/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。