Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
chore: feat: added Effect.tapErrorTag
Browse files Browse the repository at this point in the history
  • Loading branch information
jessekelly881 committed Aug 13, 2023
1 parent 49f1405 commit f068c4d
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/tidy-carpets-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect/io": patch
---

added Effect.tapErrorTag
17 changes: 17 additions & 0 deletions dtslint/Effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,3 +372,20 @@ Effect.promise<string>(
}, 2000)
})
)

class TestError1 {
readonly _tag = "TestError1"
constructor() {}
}

// $ExpectType Effect<never, TestError1, never>
pipe(
Effect.fail(new TestError1()),
Effect.tapErrorTag("TestError1", () => Effect.succeed(1))
)

// $ExpectType Effect<never, TestError1 | Error, never>
pipe(
Effect.fail(new TestError1()),
Effect.tapErrorTag("TestError1", () => Effect.fail(new Error("")))
)
18 changes: 18 additions & 0 deletions src/Effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3618,6 +3618,24 @@ export const tapError: {
<R, E, XE extends E, A, R2, E2, X>(self: Effect<R, E, A>, f: (e: XE) => Effect<R2, E2, X>): Effect<R | R2, E | E2, A>
} = effect.tapError

/**
* Returns an effect that effectfully "peeks" at the specific tagged failure of this effect.
*
* @since 1.0.0
* @category sequencing
*/
export const tapErrorTag: {
<K extends E["_tag"] & string, E extends { _tag: string }, R1, E1, A1>(
k: K,
f: (e: Extract<E, { _tag: K }>) => Effect<R1, E1, A1>
): <R, A>(self: Effect<R, E, A>) => Effect<R | R1, E | E1, A>
<R, E extends { _tag: string }, A, K extends E["_tag"] & string, R1, E1, A1>(
self: Effect<R, E, A>,
k: K,
f: (e: Extract<E, { _tag: K }>) => Effect<R1, E1, A1>
): Effect<R | R1, E | E1, A>
} = effect.tapErrorTag

/**
* Returns an effect that effectually "peeks" at the cause of the failure of
* this effect.
Expand Down
19 changes: 19 additions & 0 deletions src/internal/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1510,6 +1510,25 @@ export const tapError = dual<
onSuccess: core.succeed
}))

/* @internal */
export const tapErrorTag = dual<
<K extends E["_tag"] & string, E extends { _tag: string }, R1, E1, A1>(
k: K,
f: (e: Extract<E, { _tag: K }>) => Effect.Effect<R1, E1, A1>
) => <R, A>(self: Effect.Effect<R, E, A>) => Effect.Effect<R | R1, E | E1, A>,
<R, E extends { _tag: string }, A, K extends E["_tag"] & string, R1, E1, A1>(
self: Effect.Effect<R, E, A>,
k: K,
f: (e: Extract<E, { _tag: K }>) => Effect.Effect<R1, E1, A1>
) => Effect.Effect<R | R1, E | E1, A>
>(3, (self, k, f) =>
tapError(self, (e) => {
if ("_tag" in e && e["_tag"] === k) {
return f(e as any)
}
return core.unit
}))

/* @internal */
export const tapErrorCause = dual<
<E, XE extends E, R2, E2, X>(
Expand Down
29 changes: 29 additions & 0 deletions test/Effect/tapping.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { pipe } from "@effect/data/Function"
import * as Effect from "@effect/io/Effect"
import { describe, expect, it } from "vitest"

class TestError1 {
readonly _tag = "TestError1"
constructor() {}
}

class TestError2 {
readonly _tag = "TestError2"
constructor() {}
}

describe.concurrent("Effect", () => {
it("tapErrorTag", async () => {
let val = 0

await pipe(
Effect.fail<TestError1 | TestError2>(new TestError2()),
Effect.tapErrorTag("TestError1", () => Effect.sync(() => val += 1)), // not called
Effect.tapErrorTag("TestError2", () => Effect.sync(() => val += 1)), // called
Effect.catchAll(() => Effect.succeed("")),
Effect.runPromise
)

expect(val).toBe(1)
})
})

0 comments on commit f068c4d

Please sign in to comment.