Effect CommunityEC
Effect Community16mo ago
9 replies
madopcode

How to properly write a function accepting an effect and using catchTag?

I want to write a function that handles a specific tagged error converting it to a DTO.
Currently I have the following code:
// dtos.ts
export interface UserNotFoundDto {
  status: 'user-not-found';
  message: string;
}

// errors.ts
export const UserNotFoundErrorTag = 'UserNotFoundError' as const;

export class UserNotFoundError extends Error {
  readonly _tag = UserNotFoundErrorTag;

  constructor(message?: string) {
    super(message);
  }
}

// adapters.ts
export const userNotFoundDtoFactory = (
  error: UserNotFoundError,
): Effect.Effect<UserNotFoundDto> =>
  Effect.succeed({ status: 'user-not-found', message: error.message });

export const userNotFoundAdapter = <
  A,
  E,
  R,
  F extends Effect.Effect<A, E | UserNotFoundError, R>,
>(
  effect: F,
) => effect.pipe(Effect.catchTag(UserNotFoundErrorTag, userNotFoundDtoFactory));

And in this code the argument userNotFoundDtoFactory for catchTag gives me the following error:
Argument of type '(error: UserNotFoundError) => Effect.Effect<UserNotFoundDto>' is not assignable to parameter of type '(e: NoInfer<UserNotFoundError | Extract<E, { _tag: "UserNotFoundError"; }>>) => Effect<UserNotFoundDto, never, never>'.
  Types of parameters 'error' and 'e' are incompatible.
    Type 'NoInfer<UserNotFoundError | Extract<E, { _tag: "UserNotFoundError"; }>>' is not assignable to type 'UserNotFoundError'.
      Type 'Extract<E, { _tag: "UserNotFoundError"; }>' is not assignable to type 'UserNotFoundError'.
        Type '{ _tag: "UserNotFoundError"; }' is missing the following properties from type 'UserNotFoundError': name, message

Looking at the typings of catchTag I think it would be better to use a constrained generic type parameter instead of Extract in this case but that's just my 2 cents.
The main question is: is it possible to write a function that accepts an effect, requires this effect to contain a specific error and handles this error while producing the correct Effect type as a result?
Was this page helpful?