# @gainratio/errors 中文文档

规范地址：https://npmcn.com/package/%40gainratio/errors/

版本：0\.4\.0
npm 元数据更新时间：2026-10-25T18:56:27.011Z
中文译文更新时间：2026-11-15T21:11:11.021Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40gainratio/errors
原文对照：https://npmcn.com/package/%40gainratio/errors/?lang=original
项目主页：https://github.com/gainratio/errors#readme
源码仓库：https://github.com/gainratio/errors

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：137 kB，35 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.13
- 运行依赖：0 个
- 首次发布：2026-10-02T13:41:46.759Z
- 最新版本发布：2026-10-25T18:56:26.593Z
- 近 30 天下载量：4185（2026-10-16 至 2026-11-14，npm 官方下载统计）
- 已发布版本数：5（近 12 个月 5 个）

## 中文简介

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

## 安装

```sh
npm install @gainratio/errors
```

也可以使用：`pnpm add @gainratio/errors`、`yarn add @gainratio/errors`、`bun add @gainratio/errors`

## README

# @ reconratio/ 错误

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

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

[![CI](https://github.com/gainratio/errors/actions/workflows/ci.yml/badge.svg)](https://github.com/gainratio/errors/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/@gainratio/errors)](https://www.npmjs.com/package/@gainratio/errors) [![License: MIT](https://img.shields.io/github/license/gainratio/errors)](https://npmcn.com/package/%40gainratio/errors/LICENSE)

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

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

**技术文件:** [建筑](https://npmcn.com/package/%40gainratio/errors/docs/ARCHITECTURE.md) • 妇女 [API 指南](https://npmcn.com/package/%40gainratio/errors/docs/API.md) • 妇女 [开始开发者](https://npmcn.com/package/%40gainratio/errors/docs/GETTING_STARTED.md)

## 试试看

1.  制作空项目并安装软件包 :
    
    ```bash
    mkdir try-errors && cd try-errors && npm init -y >/dev/null && npm install @gainratio/errors
    ```
    
2.  另存为 `try.mjs` (这是 [`examples/try.mjs`](https://npmcn.com/package/%40gainratio/errors/examples/try.mjs):
    

```js
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));
```

3.  运行 `node try.mjs`。这是此代码中的真正输出 仓库 :

```text
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` 首先列出(参见 [从哪一个代码列表开始](https://npmcn.com/package/%40gainratio/errors/#readme-which-list-of-codes-to-start-from)) (中文(简体) ). 这个 茶壶没有匹配,所以它掉回 `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 已经使用 :

```bash
npm install @gainratio/errors i18next
```

另存为 `languages.mjs` (这是 [`examples/languages.mjs`](https://npmcn.com/package/%40gainratio/errors/examples/languages.mjs)运行 `node languages.mjs`数字 :

```js
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));
```

实际输出 :

```text
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 指南](https://npmcn.com/package/%40gainratio/errors/docs/API.md#show-errors-in-the-users-language) 有细节.

## 如何运作

```mermaid
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个现成名单. 它们是可选的。 您也可以写 每一个代码你自己.

| 列表 | 代码 | 用它当 |
| --- | --- | --- |
| `corePack` | 10个 | 几乎总是。 每天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`编辑 [建筑](https://npmcn.com/package/%40gainratio/errors/docs/ARCHITECTURE.md) 医生列表 两种情况都一样.

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

## 它不会做的

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

## 什么时候用别的东西

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

## 安装

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

它需要节点22.13或更新而无依赖性. 没有什么 配置 。 唯一的设置是当没有匹配时返回哪个代码(参见 页:1 [API 指南](https://npmcn.com/package/%40gainratio/errors/docs/API.md)) (中文(简体) ).

## 开发

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

`pnpm gate` 运行 lint、 类型检查、 100%覆盖栏的测试以及 建设。 同样的指令CI运行,需要不到20秒。 开始 [开始开发者](https://npmcn.com/package/%40gainratio/errors/docs/GETTING_STARTED.md),覆盖节点 要使用的版本,代码的映射,以及第一次修改的行走.

## 详细情况

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

## 许可证

麻省理工学院. 见 [自由主义](https://npmcn.com/package/%40gainratio/errors/LICENSE)。 。 。 .

## 常见问题

### @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 和提交记录判断。

