diff --git a/.changeset/sweet-maps-return.md b/.changeset/sweet-maps-return.md new file mode 100644 index 00000000000..7684f514d4c --- /dev/null +++ b/.changeset/sweet-maps-return.md @@ -0,0 +1,5 @@ +--- +"effect": minor +--- + +allow catching multiple different tags in Effect.catchTag diff --git a/packages/effect/src/Effect.ts b/packages/effect/src/Effect.ts index f2d46f1ac7f..4c5af0bbad8 100644 --- a/packages/effect/src/Effect.ts +++ b/packages/effect/src/Effect.ts @@ -3861,15 +3861,13 @@ export const catchSomeDefect: { * @category Error handling */ export const catchTag: { - ( - k: K, - f: (e: NoInfer>) => Effect - ): (self: Effect) => Effect, R1 | R> - ( + , A1, E1, R1>( + ...args: [...tags: K, f: (e: Extract, { _tag: K[number] }>) => Effect] + ): (self: Effect) => Effect | E1, R | R1> + , R1, E1, A1>( self: Effect, - k: K, - f: (e: Extract) => Effect - ): Effect, R | R1> + ...args: [...tags: K, f: (e: Extract, { _tag: K[number] }>) => Effect] + ): Effect | E1, R | R1> } = effect.catchTag /** diff --git a/packages/effect/src/internal/core-effect.ts b/packages/effect/src/internal/core-effect.ts index 52ad8c7df8f..83e9bba8d10 100644 --- a/packages/effect/src/internal/core-effect.ts +++ b/packages/effect/src/internal/core-effect.ts @@ -237,21 +237,36 @@ export const catchSomeDefect = dual< /* @internal */ export const catchTag = dual< - ( - k: K, - f: (e: Extract) => Effect.Effect - ) => (self: Effect.Effect) => Effect.Effect | E1, R | R1>, - ( + , A1, E1, R1>( + ...args: [...tags: K, f: (e: Extract, { _tag: K[number] }>) => Effect.Effect] + ) => (self: Effect.Effect) => Effect.Effect | E1, R | R1>, + , R1, E1, A1>( self: Effect.Effect, - k: K, - f: (e: Extract) => Effect.Effect - ) => Effect.Effect | E1, R | R1> ->(3, ( - self: Effect.Effect, - k: K, - f: (e: Extract) => Effect.Effect -): Effect.Effect | E1, R | R1> => - core.catchIf(self, Predicate.isTagged(k) as Predicate.Refinement>, f) as any) + ...args: [...tags: K, f: (e: Extract, { _tag: K[number] }>) => Effect.Effect] + ) => Effect.Effect | E1, R | R1> +>( + (args: any) => core.isEffect(args[0]), + , R1, E1, A1>( + self: Effect.Effect, + ...args: [...tags: K, f: (e: Extract, { _tag: K[number] }>) => Effect.Effect] + ): Effect.Effect | E1, R | R1> => { + const f = args[args.length - 1] as any + let predicate: Predicate.Predicate + if (args.length === 2) { + predicate = Predicate.isTagged(args[0] as string) + } else { + predicate = (e) => { + const tag = Predicate.hasProperty(e, "_tag") ? e["_tag"] : undefined + if (!tag) return false + for (let i = 0; i < args.length - 1; i++) { + if (args[i] === tag) return true + } + return false + } + } + return core.catchIf(self, predicate as Predicate.Refinement>, f) as any + } +) /** @internal */ export const catchTags: {