mcpField
E
effect-ts-errors

effect-ts-errors

github.com/mrevanzak开发897 次安装40 周前更新
代码仓库

关于 effect-ts-errors

面向使用 Effect-TS 定义领域错误或验证数据的开发者,介绍类型化错误处理。内容涵盖标记错误、定向处理及收集多个验证失败。

主要功能

  1. 01定义标记错误类型
  2. 02按标记处理错误
  3. 03处理错误通道中的全部错误
  4. 04累积验证结果

适用场景

  1. 01建模可区分的领域错误
  2. 02处理指定错误类型
  3. 03同时验证多个字段

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mrevanzak/effect-ts-skills --skill effect-ts-errors

安装后在 Claude Code 中输入/effect-ts-errors确认已加载。

详细介绍

Effect-TS 错误处理

概述

Effect-TS 提供了一个类型安全的错误通道(Effect<A, E, R> 中的 E),用于追踪可能发生的故障。使用带标签错误来区分错误,并使用专用组合器处理或累积错误。

使用场景

  • 为领域逻辑定义自定义错误类型。
  • 在不捕获所有错误的情况下处理特定错误。
  • 验证多个字段并收集所有错误。

不适用场景:

  • 在非 Effect 代码中使用简单的 try/catch。
  • 无需区分错误类型时(使用 Effect.fail(message))。

核心模式

之前(通用错误):

if (!user) throw new Error("Not found");

之后(带标签错误):

if (!user) return yield* new UserNotFoundError({ userId: id });

快速参考

特性方法用途
定义错误Data.TaggedError创建可区分的类型化错误。
捕获一个错误Effect.catchTag根据特定带标签错误的 _tag 处理该错误。
捕获所有错误Effect.catchAll处理错误通道中的所有错误。
累积错误Effect.all(..., { mode: 'either' })将多个结果/错误收集到 Either[] 中。

实现

1. 带标签错误
import { Data, Effect } from 'effect';

export class UserNotFoundError extends Data.TaggedError('UserNotFoundError')<{
  userId: string;
}> {}

export class DatabaseError extends Data.TaggedError('DatabaseError')<{
  message: string;
}> {}

const getUser = (id: string): Effect.Effect<User, UserNotFoundError | DatabaseError> =>
  Effect.gen(function* () {
    const result = yield* queryDatabase(id);
    if (!result) return yield* new UserNotFoundError({ userId: id });
    return result;
  });
2. 捕获特定错误
const handled = getUser(id).pipe(
  // catchTag only works on objects with a _tag property
  Effect.catchTag('UserNotFoundError', (e) => 
    Effect.succeed({ id: e.userId, name: 'Guest' })
  )
);
// Result: Effect<User, DatabaseError>
3. 错误累积
import { Either, Effect } from 'effect';

const validateAll = (data: Input) =>
  Effect.gen(function* () {
    const results = yield* Effect.all([
      validateEmail(data.email),
      validateAge(data.age)
    ], { mode: 'either' });
    
    const errors = results.filter(Either.isLeft).map(e => e.left);
    if (errors.length > 0) return yield* Effect.fail(errors);
    return results.map(e => (e as Either.Right<any, any>).right);
  });

常见错误

  • 使用 throw:会破坏错误通道。始终使用 Effect.fail 或 yield* new TaggedError()。
  • 通用的 catchAll:会吞掉你原本不打算处理的错误。优先使用 catchTag。
  • 提前终止:默认情况下,Effect.all 会在遇到第一个错误时停止。使用 { mode: 'either' } 或 { mode: 'validate' } 来累积错误。

必需背景知识: 使用 effect-ts-fundamentals 了解核心概念。

评论

支持 Markdown