@deliverart/sdk-js-error-handler

中文文档
3.0.1发布于 2026/11/11TypeScriptESM + CJS近 30 天下载 3036

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

中文使用文档
文档目录24 节
  1. 安装
  2. 导出类型
  3. 错误汉德勒普吕金
  4. 痛苦
  5. ApiErrorData 数据
  6. 校验 ErrorData
  7. 窗体状态
  8. 窗体状态错误
  9. 使用量
  10. 基本设置
  11. 处理校验错误
  12. 在窗体中显示校验错误
  13. 处理不同的 HTTP 状态代码
  14. 使用带有反应服务器动作的窗体状态
  15. 全局错误处理器
  16. 类型警卫
  17. 将窗体状态错误转换为例外
  18. 如何运作
  19. 最佳做法
  20. 1. 集中处理出错
  21. 2. 实地一级误差绘图
  22. 3. 托拉斯通知
  23. 许可证
  24. 安全诊断

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

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

安装

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

导出类型

错误汉德勒普吕金

class ErrorHandlerPlugin implements ApiClientPlugin<{}>

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

构造器 :

  • constructor() - 不需要配置

痛苦

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 数据

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

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

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

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

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

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

校验 ErrorData

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 - 错误标题

窗体状态

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

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

窗体状态错误

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

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

使用量

基本设置

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());

处理校验错误

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.
  }
}

在窗体中显示校验错误

反应示例

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 状态代码

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 服务器动作特别有用:

// 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 };
  });
}
// 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 错误设置全局错误处理器 :

// 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.');
  }
}
// Usage in your app
try {
  await client.call(request);
} catch (error) {
  handleApiError(error);
}

类型警卫

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

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();
  }
}

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

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. 集中处理出错

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

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. 实地一级误差绘图

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

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. 托拉斯通知

与土司通知库合并:

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 共发布 321 个版本,首次发布于 2025/06/16;过去 12 个月发布了 230 个版本。

版本发布日期距今
3.0.1latest2026/11/111 天前
3.0.02026/11/092 天前
3.0.0-dev.1dev2026/11/092 天前
2.48.12026/10/2518 天前
2.48.02026/10/2319 天前
2.47.02026/10/2319 天前

关于 @deliverart/sdk-js-error-handler 的常见问题

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