mcpField
E
effect-ts-errors

effect-ts-errors

github.com/mrevanzakDevelopment897 installsUpdated 40w ago
Repository

About effect-ts-errors

A skill guide to typed error handling in Effect-TS for developers defining domain errors or validating data. It explains tagged errors, targeted handling, and collecting multiple validation failures.

Key features

  1. 01Define tagged error types
  2. 02Handle errors by tag
  3. 03Handle all errors in a channel
  4. 04Accumulate validation results

Use cases

  1. 01Modeling distinguishable domain failures
  2. 02Handling selected error cases
  3. 03Validating multiple fields together

Install

Copy the command and run it in a terminal.

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

After installing, type/effect-ts-errorsin Claude Code to confirm it loaded.

Details

From the project README

Effect-TS Error Handling

Overview

Effect-TS provides a type-safe error channel (E in Effect<A, E, R>) that tracks potential failures. Use Tagged Errors for distinguishability and specialized combinators for handling or accumulating errors.

When to Use

  • Defining custom error types for domain logic.
  • Handling specific errors without catching everything.
  • Validating multiple fields and collecting all failures.

When NOT to use:

  • Simple try/catch for non-Effect code.
  • When error types don't need to be distinguished (use Effect.fail(message)).

Core Pattern

Before (Generic Errors):

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

After (Tagged Errors):

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

Quick Reference

FeatureMethodPurpose
Define ErrorData.TaggedErrorCreate distinguishable, typed errors.
Catch OneEffect.catchTagHandle a specific tagged error by its _tag.
Catch AllEffect.catchAllHandle all errors in the channel.
AccumulateEffect.all(..., { mode: 'either' })Collect multiple results/errors into Either[].

Implementation

1. Tagged Errors
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. Catching Specific Errors
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. Error Accumulation
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);
  });

Common Mistakes

  • Using throw: Breaks the error channel. Always use Effect.fail or yield* new TaggedError().
  • Generic catchAll: Swallows errors you didn't intend to handle. Prefer catchTag.
  • Short-circuiting: Effect.all stops at the first error by default. Use { mode: 'either' } or { mode: 'validate' } for accumulation.

REQUIRED BACKGROUND: Use effect-ts-fundamentals for core concepts.

Comments

Markdown supported