# @deliverart/sdk-js-error-handler 中文文档

规范地址：https://npmcn.com/package/%40deliverart/sdk-js-error-handler/

版本：3\.0\.1
npm 元数据更新时间：2026-11-10T20:25:56.326Z
中文译文更新时间：2026-11-12T03:42:27.807Z
软件包许可：未声明

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

原始 npm 页面：https://www.npmjs.com/package/%40deliverart/sdk-js-error-handler
原文对照：https://npmcn.com/package/%40deliverart/sdk-js-error-handler/?lang=original

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

- 包体积（解压后）：29.5 kB，6 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：2 个
- 首次发布：2025-06-16T15:32:16.576Z
- 最新版本发布：2026-11-10T20:25:56.162Z
- 近 30 天下载量：3036（2026-10-12 至 2026-11-10，npm 官方下载统计）
- 已发布版本数：321（近 12 个月 230 个）

## 中文简介

在 JavaScript 中处理 SDK 交付工具出错

## 安装

```sh
npm install @deliverart/sdk-js-error-handler
```

也可以使用：`pnpm add @deliverart/sdk-js-error-handler`、`yarn add @deliverart/sdk-js-error-handler`、`bun add @deliverart/sdk-js-error-handler`

## README

# @ deliverart/ sdk-js- error- 手持器

交付艺术 JavaScript SDK 的处理插件出错 。 自动处理 API 出错,并将其转换为已键入的例外.

## 安装

```bash
npm install @deliverart/sdk-js-error-handler @deliverart/sdk-js-core
# or
pnpm add @deliverart/sdk-js-error-handler @deliverart/sdk-js-core
# or
yarn add @deliverart/sdk-js-error-handler @deliverart/sdk-js-core
```

## 导出类型

### 错误汉德勒普吕金

```typescript
class ErrorHandlerPlugin implements ApiClientPlugin<{}>
```

用于截取 API 响应并转换出出出错响应的插件 .

**构造器 :**

-   `constructor()` - 不需要配置

### 痛苦

```typescript
class ApiError extends Error {
  readonly name = 'ApiError'
  readonly code?: string
  readonly request?: RequestInit
  readonly response?: Response
  readonly status?: number
  readonly data?: ApiErrorData
}
```

API 错误的主要错误类.

**属性 :**

-   `name: 'ApiError'` - 错误名称
-   `code?: string` - API错误代码
-   `request?: RequestInit` - 原始请求
-   `response?: Response` - HTTP 响应对象
-   `status?: number` - HTTP状态代码
-   `data?: ApiErrorData` - 输入错误数据

### ApiErrorData 数据

```typescript
type ApiErrorData =
  | {
      type: 'VALIDATION_ERROR'
      value: ValidationErrorData
    }
  | {
      type: 'UNKNOWN_ERROR'
      value: unknown
    }
```

对不同的错误类型进行区分的结合类型.

**评估 错误** - 在API回复422状态时返回(验证失败)

-   `value: ValidationErrorData` - 含有违反审定规定的情况

**未知错误** - 返回处理所有其他错误

-   `value: unknown` - 包含原始错误反应

### 校验 ErrorData

```typescript
interface ValidationErrorData {
  status: number
  violations: Array<{
    propertyPath: string
    message: string
    code: string | null
  }>
  detail: string
  type: string
  title: string
}
```

API结构化验证错误数据.

**属性 :**

-   `status: number` - HTTP状态代码(422)
-   `violations: Array` - 违反审定清单
    -   `propertyPath: string` - 无法验证的外地路径(例如“电子邮件”、“地址.city”)
    -   `message: string` - 人类可读错误信息
    -   `code: string | null` - 验证错误代码
-   `detail: string` - 详细错误描述
-   `type: string` - 错误类型标识符
-   `title: string` - 错误标题

### 窗体状态

```typescript
type FormState<T> =
  | {
      success: true
      data: T
    }
  | {
      success: false
      error: ApiErrorData
    }
```

处理表单提交状态的工具类型( 用于 React 服务器动作) .

### 窗体状态错误

```typescript
class FormStateError extends Error {
  constructor(public readonly error: ApiErrorData)
}
```

窗体状态错误的错误包装器 .

## 使用量

### 基本设置

```typescript
import { createApiClient } from '@deliverart/sdk-js-core';
import { ErrorHandlerPlugin } from '@deliverart/sdk-js-error-handler';

const client = createApiClient({ 
  baseUrl: 'https://api.deliverart.com' 
})
  .addPlugin(new ErrorHandlerPlugin());
```

### 处理校验错误

```typescript
import { ApiError } from '@deliverart/sdk-js-error-handler';
import { CreateUser } from './requests';

try {
  await client.call(new CreateUser({
    email: 'invalid-email',
    name: ''
  }));
} catch (error) {
  if (error instanceof ApiError && error.data?.type === 'VALIDATION_ERROR') {
    const violations = error.data.value.violations;
    
    violations.forEach(violation => {
      console.error(`${violation.propertyPath}: ${violation.message}`);
    });
    
    // Output:
    // email: This value is not a valid email address.
    // name: This value should not be blank.
  }
}
```

### 在窗体中显示校验错误

#### 反应示例

```typescript
import { useState } from 'react';
import { ApiError } from '@deliverart/sdk-js-error-handler';

function CreateUserForm() {
  const [errors, setErrors] = useState<Record<string, string>>({});
  
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setErrors({});
    
    try {
      await client.call(new CreateUser(formData));
      // Success!
    } catch (error) {
      if (error instanceof ApiError && error.data?.type === 'VALIDATION_ERROR') {
        const newErrors: Record<string, string> = {};
        
        error.data.value.violations.forEach(violation => {
          newErrors[violation.propertyPath] = violation.message;
        });
        
        setErrors(newErrors);
      }
    }
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <input name="email" />
      {errors.email && <span className="error">{errors.email}</span>}
      
      <input name="name" />
      {errors.name && <span className="error">{errors.name}</span>}
      
      <button type="submit">Create User</button>
    </form>
  );
}
```

### 处理不同的 HTTP 状态代码

```typescript
import { ApiError } from '@deliverart/sdk-js-error-handler';

try {
  await client.call(new GetUser('123'));
} catch (error) {
  if (error instanceof ApiError) {
    switch (error.status) {
      case 400:
        console.error('Bad Request:', error.message);
        break;
      case 401:
        console.error('Unauthorized - please login');
        window.location.href = '/login';
        break;
      case 403:
        console.error('Forbidden - insufficient permissions');
        break;
      case 404:
        console.error('User not found');
        break;
      case 422:
        // Validation error - handled above
        break;
      case 500:
        console.error('Server error');
        break;
      default:
        console.error('Unknown error:', error);
    }
  }
}
```

### 使用带有反应服务器动作的窗体状态

FormState对 Next.js 服务器动作特别有用:

```typescript
// app/actions/create-user.ts
'use server';

import { throwableToFormState, FormState } from '@deliverart/sdk-js-error-handler';
import { sdk } from '@/lib/sdk';
import { CreateUser } from '@deliverart/sdk-js-user';

export async function createUserAction(
  formData: FormData
): Promise<FormState<{ id: string }>> {
  return throwableToFormState(async () => {
    const result = await sdk.call(new CreateUser({
      name: formData.get('name') as string,
      email: formData.get('email') as string,
    }));
    
    return { id: result.id };
  });
}
```

```typescript
// app/components/CreateUserForm.tsx
'use client';

import { useFormState } from 'react-dom';
import { createUserAction } from '../actions/create-user';

export function CreateUserForm() {
  const [state, formAction] = useFormState(createUserAction, null);
  
  return (
    <form action={formAction}>
      <input name="name" required />
      {state?.success === false && 
       state.error.type === 'VALIDATION_ERROR' && 
       state.error.value.violations
         .filter(v => v.propertyPath === 'name')
         .map(v => <span key={v.code} className="error">{v.message}</span>)
      }
      
      <input name="email" type="email" required />
      {state?.success === false && 
       state.error.type === 'VALIDATION_ERROR' && 
       state.error.value.violations
         .filter(v => v.propertyPath === 'email')
         .map(v => <span key={v.code} className="error">{v.message}</span>)
      }
      
      <button type="submit">Create User</button>
      
      {state?.success === true && (
        <p className="success">User created with ID: {state.data.id}</p>
      )}
    </form>
  );
}
```

### 全局错误处理器

为所有 API 错误设置全局错误处理器 :

```typescript
// lib/error-handler.ts
import { ApiError } from '@deliverart/sdk-js-error-handler';

export function handleApiError(error: unknown) {
  if (!(error instanceof ApiError)) {
    console.error('Non-API error:', error);
    return;
  }
  
  // Log to error tracking service (e.g., Sentry)
  console.error('API Error:', {
    status: error.status,
    code: error.code,
    message: error.message,
    data: error.data,
  });
  
  // Show user-friendly message
  if (error.status === 401) {
    alert('Please login to continue');
    window.location.href = '/login';
  } else if (error.status === 403) {
    alert('You do not have permission to perform this action');
  } else if (error.status === 404) {
    alert('The requested resource was not found');
  } else if (error.data?.type === 'VALIDATION_ERROR') {
    const firstViolation = error.data.value.violations[0];
    alert(`Validation error: ${firstViolation.message}`);
  } else {
    alert('An unexpected error occurred. Please try again.');
  }
}
```

```typescript
// Usage in your app
try {
  await client.call(request);
} catch (error) {
  handleApiError(error);
}
```

### 类型警卫

创建清洁错误处理的类型保护 :

```typescript
import { ApiError, ApiErrorData } from '@deliverart/sdk-js-error-handler';

function isValidationError(error: unknown): error is ApiError & { 
  data: { type: 'VALIDATION_ERROR', value: ValidationErrorData } 
} {
  return error instanceof ApiError && 
         error.data?.type === 'VALIDATION_ERROR';
}

function isUnauthorizedError(error: unknown): error is ApiError {
  return error instanceof ApiError && error.status === 401;
}

function isNotFoundError(error: unknown): error is ApiError {
  return error instanceof ApiError && error.status === 404;
}

// Usage
try {
  await client.call(request);
} catch (error) {
  if (isValidationError(error)) {
    // TypeScript knows error.data.value is ValidationErrorData
    error.data.value.violations.forEach(v => {
      console.log(v.propertyPath, v.message);
    });
  } else if (isUnauthorizedError(error)) {
    redirectToLogin();
  } else if (isNotFoundError(error)) {
    show404Page();
  }
}
```

### 将窗体状态错误转换为例外

```typescript
import { formStateErrorToThrowable, FormState } from '@deliverart/sdk-js-error-handler';

const result: FormState<User> = await createUserAction(formData);

if (!result.success) {
  // Convert FormState error back to throwable error
  throw formStateErrorToThrowable(result.error);
}

// TypeScript knows result.data is User
console.log(result.data.id);
```

## 如何运作

插件增加了一个响应中间软件:

1.  检查响应是否正确( E)`!response.ok`(中文(简体) )
2.  如果状态为 422, 尝试将响应解析为验证错误
3.  如果解析成功,则投掷 `ApiError` 与 `VALIDATION_ERROR` 类型
4.  对于所有其他错误反应,丢弃 `ApiError` 与 `UNKNOWN_ERROR` 类型
5.  包括错误中的原始请求、响应和解析体

## 最佳做法

### 1\. 集中处理出错

为整个应用程序的一致错误处理创建工具函数 :

```typescript
export function getErrorMessage(error: unknown): string {
  if (error instanceof ApiError) {
    if (error.data?.type === 'VALIDATION_ERROR') {
      const firstViolation = error.data.value.violations[0];
      return firstViolation?.message ?? 'Validation failed';
    }
    return error.message;
  }
  
  if (error instanceof Error) {
    return error.message;
  }
  
  return 'An unexpected error occurred';
}
```

### 2\. 实地一级误差绘图

创建一个用于映射违法行为以形成字段的助手 :

```typescript
import { ValidationErrorData } from '@deliverart/sdk-js-error-handler';

export function violationsToFieldErrors(
  violations: ValidationErrorData['violations']
): Record<string, string> {
  return violations.reduce((acc, violation) => {
    acc[violation.propertyPath] = violation.message;
    return acc;
  }, {} as Record<string, string>);
}

// Usage
if (error.data?.type === 'VALIDATION_ERROR') {
  const fieldErrors = violationsToFieldErrors(error.data.value.violations);
  setErrors(fieldErrors);
}
```

### 3\. 托拉斯通知

与土司通知库合并:

```typescript
import { toast } from 'sonner';
import { ApiError } from '@deliverart/sdk-js-error-handler';

try {
  await client.call(request);
  toast.success('Operation completed successfully');
} catch (error) {
  if (error instanceof ApiError && error.data?.type === 'VALIDATION_ERROR') {
    error.data.value.violations.forEach(v => {
      toast.error(v.message);
    });
  } else {
    toast.error('An error occurred');
  }
}
```

## 许可证

麻省理工学院

## 安全诊断

`ApiError` 保持原样 `request`, (中文(简体) ), `response`, (中文(简体) ), `data`, (中文(简体) ), `code`, (中文(简体) ), `status` 和可以读取给输入的消费者和窗体状态转换的信息。 运输物体、生体和状态/代码字段是不可假定的。 默认节点检查,字符串格式化和JSON序列化只暴露出一个允许的列表诊断:稳定的分类,HTTP状态/代码,方法和一个路径名,没有查询,碎片,来源或用户信息. 插件从实际请求上下文中抓取路径名 。 实地审定信息仍然有方案,没有列入这些诊断.

不记录原始 `error.request`, (中文(简体) ), `error.response`, (中文(简体) ), `error.data`,自定义调用器消息或任意堆栈/例外序列器。 此 SDK 行为不会将 Next.js 访问日志, OAuth 回调 URL 在别处登录, 或独立遥测请求上下文 .

重点建设-工艺测试进行无害环境管理和普通JS诊断、秘密遗漏、实际反应中间软件和形式状态相容性。 构建此软件包及其工作空间依赖, 然后运行 `pnpm --filter @deliverart/sdk-js-error-handler test`,不添加测试跑者依赖性:测试使用节点内置跑者.

## 常见问题

### @deliverart/sdk-js-error-handler 是什么？

在 JavaScript 中处理 SDK 交付工具出错

### 如何安装 @deliverart/sdk-js-error-handler？

在项目目录运行 npm install @deliverart/sdk-js-error-handler，或使用 pnpm add / yarn add / bun add。

### @deliverart/sdk-js-error-handler 支持 TypeScript 吗？

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

### @deliverart/sdk-js-error-handler 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @deliverart/sdk-js-error-handler 可以商用吗？

@deliverart/sdk-js-error-handler 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @deliverart/sdk-js-error-handler 的下载量有多少？

根据 npm 官方下载统计，@deliverart/sdk-js-error-handler 在 2026/10/12 – 2026/11/10 这 30 天内被下载 3,036 次，日均约 101 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @deliverart/sdk-js-error-handler 还在维护吗？

最新版本 3\.0\.1 发布于 2026/11/11（1 天前）；至今共发布 321 个版本，其中过去 12 个月发布了 230 个；首次发布于 2025/06/16。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

