关于 effect-ts-errors
面向使用 Effect-TS 定义领域错误或验证数据的开发者,介绍类型化错误处理。内容涵盖标记错误、定向处理及收集多个验证失败。
主要功能
- 01定义标记错误类型
- 02按标记处理错误
- 03处理错误通道中的全部错误
- 04累积验证结果
适用场景
- 01建模可区分的领域错误
- 02处理指定错误类型
- 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