Skip to content

Commit 845bccf

Browse files
tim-smarteffect-bot
authored andcommitted
allow catching multiple different tags in Effect.catchTag (#4796)
1 parent 45e5d5a commit 845bccf

File tree

3 files changed

+40
-22
lines changed

3 files changed

+40
-22
lines changed

.changeset/sweet-maps-return.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect": minor
3+
---
4+
5+
allow catching multiple different tags in Effect.catchTag

packages/effect/src/Effect.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -3861,15 +3861,13 @@ export const catchSomeDefect: {
38613861
* @category Error handling
38623862
*/
38633863
export const catchTag: {
3864-
<K extends E extends { _tag: string } ? E["_tag"] : never, E, A1, E1, R1>(
3865-
k: K,
3866-
f: (e: NoInfer<Extract<E, { _tag: K }>>) => Effect<A1, E1, R1>
3867-
): <A, R>(self: Effect<A, E, R>) => Effect<A1 | A, E1 | Exclude<E, { _tag: K }>, R1 | R>
3868-
<A, E, R, K extends E extends { _tag: string } ? E["_tag"] : never, R1, E1, A1>(
3864+
<E, const K extends RA.NonEmptyReadonlyArray<E extends { _tag: string } ? E["_tag"] : never>, A1, E1, R1>(
3865+
...args: [...tags: K, f: (e: Extract<NoInfer<E>, { _tag: K[number] }>) => Effect<A1, E1, R1>]
3866+
): <A, R>(self: Effect<A, E, R>) => Effect<A | A1, Exclude<E, { _tag: K[number] }> | E1, R | R1>
3867+
<A, E, R, const K extends RA.NonEmptyReadonlyArray<E extends { _tag: string } ? E["_tag"] : never>, R1, E1, A1>(
38693868
self: Effect<A, E, R>,
3870-
k: K,
3871-
f: (e: Extract<E, { _tag: K }>) => Effect<A1, E1, R1>
3872-
): Effect<A | A1, E1 | Exclude<E, { _tag: K }>, R | R1>
3869+
...args: [...tags: K, f: (e: Extract<NoInfer<E>, { _tag: K[number] }>) => Effect<A1, E1, R1>]
3870+
): Effect<A | A1, Exclude<E, { _tag: K[number] }> | E1, R | R1>
38733871
} = effect.catchTag
38743872

38753873
/**

packages/effect/src/internal/core-effect.ts

+29-14
Original file line numberDiff line numberDiff line change
@@ -237,21 +237,36 @@ export const catchSomeDefect = dual<
237237

238238
/* @internal */
239239
export const catchTag = dual<
240-
<K extends (E extends { _tag: string } ? E["_tag"] : never), E, A1, E1, R1>(
241-
k: K,
242-
f: (e: Extract<E, { _tag: K }>) => Effect.Effect<A1, E1, R1>
243-
) => <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | A1, Exclude<E, { _tag: K }> | E1, R | R1>,
244-
<A, E, R, K extends (E extends { _tag: string } ? E["_tag"] : never), R1, E1, A1>(
240+
<E, const K extends Arr.NonEmptyReadonlyArray<E extends { _tag: string } ? E["_tag"] : never>, A1, E1, R1>(
241+
...args: [...tags: K, f: (e: Extract<NoInfer<E>, { _tag: K[number] }>) => Effect.Effect<A1, E1, R1>]
242+
) => <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | A1, Exclude<E, { _tag: K[number] }> | E1, R | R1>,
243+
<A, E, R, const K extends Arr.NonEmptyReadonlyArray<E extends { _tag: string } ? E["_tag"] : never>, R1, E1, A1>(
245244
self: Effect.Effect<A, E, R>,
246-
k: K,
247-
f: (e: Extract<E, { _tag: K }>) => Effect.Effect<A1, E1, R1>
248-
) => Effect.Effect<A | A1, Exclude<E, { _tag: K }> | E1, R | R1>
249-
>(3, <A, E, R, K extends (E extends { _tag: string } ? E["_tag"] : never), R1, E1, A1>(
250-
self: Effect.Effect<A, E, R>,
251-
k: K,
252-
f: (e: Extract<E, { _tag: K }>) => Effect.Effect<A1, E1, R1>
253-
): Effect.Effect<A | A1, Exclude<E, { _tag: K }> | E1, R | R1> =>
254-
core.catchIf(self, Predicate.isTagged(k) as Predicate.Refinement<E, Extract<E, { _tag: K }>>, f) as any)
245+
...args: [...tags: K, f: (e: Extract<NoInfer<E>, { _tag: K[number] }>) => Effect.Effect<A1, E1, R1>]
246+
) => Effect.Effect<A | A1, Exclude<E, { _tag: K[number] }> | E1, R | R1>
247+
>(
248+
(args: any) => core.isEffect(args[0]),
249+
<A, E, R, const K extends Arr.NonEmptyReadonlyArray<E extends { _tag: string } ? E["_tag"] : never>, R1, E1, A1>(
250+
self: Effect.Effect<A, E, R>,
251+
...args: [...tags: K, f: (e: Extract<NoInfer<E>, { _tag: K[number] }>) => Effect.Effect<A1, E1, R1>]
252+
): Effect.Effect<A | A1, Exclude<E, { _tag: K[number] }> | E1, R | R1> => {
253+
const f = args[args.length - 1] as any
254+
let predicate: Predicate.Predicate<E>
255+
if (args.length === 2) {
256+
predicate = Predicate.isTagged(args[0] as string)
257+
} else {
258+
predicate = (e) => {
259+
const tag = Predicate.hasProperty(e, "_tag") ? e["_tag"] : undefined
260+
if (!tag) return false
261+
for (let i = 0; i < args.length - 1; i++) {
262+
if (args[i] === tag) return true
263+
}
264+
return false
265+
}
266+
}
267+
return core.catchIf(self, predicate as Predicate.Refinement<E, Extract<E, { _tag: K[number] }>>, f) as any
268+
}
269+
)
255270

256271
/** @internal */
257272
export const catchTags: {

0 commit comments

Comments
 (0)