1/**
2 * Represents the result of an Effect computation as a plain value.
3 *
4 * An `Exit<A, E>` is either a success with an `A` or a failure with a
5 * `Cause<E>`. The failure cause preserves typed errors, defects, and
6 * interruptions after a workflow has finished. Use this module when completed
7 * Effect results need to be inspected, transformed, filtered, or matched
8 * synchronously as data.
9 *
10 * @since 2.0.0
11 */
12import type * as Cause from "./Cause.ts"
13import type * as Effect from "./Effect.ts"
14import * as core from "./internal/core.ts"
15import * as effect from "./internal/effect.ts"
16import type { Option } from "./Option.ts"
17import type * as Result from "./Result.ts"
18import type { NoInfer } from "./Types.ts"
19
20const TypeId = core.ExitTypeId
21
22/**
23 * Represents the result of an Effect computation.
24 *
25 * **When to use**
26 *
27 * Use when you need to synchronously inspect whether an Effect computation
28 * succeeded or failed.
29 *
30 * **Details**
31 *
32 * An `Exit<A, E>` is either `Success<A, E>` containing a value of type `A`, or
33 * `Failure<A, E>` containing a `Cause<E>` describing why the computation
34 * failed.
35 *
36 * Since `Exit` is also an `Effect`, you can yield it inside `Effect.gen`.
37 *
38 * **Example** (Pattern matching on an Exit)
39 *
40 * ```ts import.meta.vitest
41 * import { Exit } from "effect"
42 *
43 * const success: Exit.Exit<number> = Exit.succeed(42)
44 * const failure: Exit.Exit<number, string> = Exit.fail("error")
45 *
46 * Exit.match(success, {
47 * onSuccess: (value) => `Got value: ${value}`,
48 * onFailure: (cause) => `Got error: ${cause}`
49 * }) // => "Got value: 42"
50 * ```
51 *
52 * @see {@link Success} for the success case
53 * @see {@link Failure} for the failure case
54 * @see {@link match} for pattern matching
55 *
56 * @category models
57 * @since 2.0.0
58 */
59export type Exit<A, E = never> = Success<A, E> | Failure<A, E>
60
61/**
62 * Namespace containing helper types shared by `Exit` values.
63 *
64 * **When to use**
65 *
66 * Use to reference helper types that describe the shared structure of `Exit`
67 * values.
68 *
69 * @since 2.0.0
70 */
71export declare namespace Exit {
72 /**
73 * Base interface shared by both Success and Failure.
74 *
75 * **When to use**
76 *
77 * Use to describe the common protocol implemented by every `Exit` value.
78 *
79 * **Details**
80 *
81 * Every Exit is also an Effect, so you can yield it in `Effect.gen`.
82 *
83 * @category models
84 * @since 4.0.0
85 */
86 export interface Proto<out A, out E = never> extends Effect.Effect<A, E> {
87 readonly [TypeId]: typeof TypeId
88 }
89}
90
91/**
92 * A successful Exit containing a value.
93 *
94 * **When to use**
95 *
96 * Use when working with the successful branch of an `Exit` after narrowing
97 * with {@link isSuccess}. Access the value via the `value` property after
98 * narrowing.
99 *
100 * **Example** (Accessing the success value)
101 *
102 * ```ts import.meta.vitest
103 * import { Exit } from "effect"
104 *
105 * const success = Exit.succeed(42)
106 *
107 * if (Exit.isSuccess(success)) {
108 * success.value // => 42
109 * }
110 * ```
111 *
112 * @see {@link isSuccess} to narrow an Exit to Success
113 * @see {@link Failure} for the failure counterpart
114 *
115 * @category models
116 * @since 2.0.0
117 */
118export interface Success<out A, out E = never> extends Exit.Proto<A, E> {
119 readonly _tag: "Success"
120 readonly value: A
121}
122
123/**
124 * A failed Exit containing a Cause.
125 *
126 * **When to use**
127 *
128 * Use when working with the failed branch of an `Exit` after narrowing with
129 * {@link isFailure}. Access the cause via the `cause` property after
130 * narrowing.
131 *
132 * **Details**
133 *
134 * The `Cause<E>` may contain typed errors, defects, or interruptions.
135 *
136 * **Example** (Accessing the failure cause)
137 *
138 * ```ts import.meta.vitest
139 * import { Cause, Exit } from "effect"
140 *
141 * const failure = Exit.fail("something went wrong")
142 *
143 * if (Exit.isFailure(failure)) {
144 * failure.cause // => Cause.fail("something went wrong")
145 * }
146 * ```
147 *
148 * @see {@link isFailure} to narrow an Exit to Failure
149 * @see {@link Success} for the success counterpart
150 *
151 * @category models
152 * @since 2.0.0
153 */
154export interface Failure<out A, out E> extends Exit.Proto<A, E> {
155 readonly _tag: "Failure"
156 readonly cause: Cause.Cause<E>
157}
158
159/**
160 * Checks whether an unknown value is an Exit.
161 *
162 * **When to use**
163 *
164 * Use to validate unknown values at system boundaries and narrow them to
165 * `Exit<unknown, unknown>`.
166 *
167 * **Details**
168 *
169 * Does not inspect the contents of the Exit. Returns `true` for both Success
170 * and Failure exits.
171 *
172 * **Example** (Checking if a value is an Exit)
173 *
174 * ```ts import.meta.vitest
175 * import { Exit } from "effect"
176 *
177 * Exit.isExit(Exit.succeed(42)) // => true
178 * Exit.isExit(Exit.fail("err")) // => true
179 * Exit.isExit("not an exit") // => false
180 * ```
181 *
182 * @see {@link isSuccess} to check for a successful Exit
183 * @see {@link isFailure} to check for a failed Exit
184 *
185 * @category guards
186 * @since 2.0.0
187 */
188export const isExit: (u: unknown) => u is Exit<unknown, unknown> = core.isExit
189
190/**
191 * Creates a successful Exit containing the given value.
192 *
193 * **When to use**
194 *
195 * Use when you need an Exit that contains a known success value.
196 *
197 * **Details**
198 *
199 * Returns a `Success<A>` with the provided value. Does not perform any
200 * computation.
201 *
202 * **Example** (Creating a successful Exit)
203 *
204 * ```ts import.meta.vitest
205 * import { Exit } from "effect"
206 *
207 * Exit.succeed(42) // => Exit.succeed(42)
208 * ```
209 *
210 * @see {@link fail} to create a failed Exit
211 * @see {@link void_ void} for a pre-allocated success with no value
212 *
213 * @category constructors
214 * @since 2.0.0
215 */
216export const succeed: <A>(a: A) => Exit<A> = core.exitSucceed
217
218/**
219 * Creates a failed Exit from a Cause.
220 *
221 * **When to use**
222 *
223 * Use when you already have a `Cause<E>` and want to wrap it in an Exit
224 * for advanced error handling where you need full control over the Cause
225 * structure.
226 *
227 * **Details**
228 *
229 * Returns a `Failure<never, E>`. If you only have an error value, use
230 * {@link fail} instead.
231 *
232 * **Example** (Creating a failed Exit from a Cause)
233 *
234 * ```ts import.meta.vitest
235 * import { Cause, Exit } from "effect"
236 *
237 * Exit.failCause(Cause.fail("Something went wrong")) // => Exit.fail("Something went wrong")
238 * ```
239 *
240 * @see {@link fail} to create a Failure from a plain error value
241 * @see {@link die} to create a Failure from a defect
242 *
243 * @category constructors
244 * @since 2.0.0
245 */
246export const failCause: <E>(cause: Cause.Cause<E>) => Exit<never, E> = core.exitFailCause
247
248/**
249 * Creates a failed Exit from a typed error value.
250 *
251 * **When to use**
252 *
253 * Use when you need to represent an expected typed failure as an `Exit`.
254 *
255 * **Details**
256 *
257 * The error is wrapped in a `Cause.Fail` internally.
258 *
259 * Returns a `Failure<never, E>`.
260 *
261 * **Example** (Creating a failed Exit)
262 *
263 * ```ts import.meta.vitest
264 * import { Exit } from "effect"
265 *
266 * Exit.fail("Something went wrong") // => Exit.fail("Something went wrong")
267 * ```
268 *
269 * @see {@link succeed} to create a successful Exit
270 * @see {@link die} to create a Failure from an unexpected defect
271 * @see {@link failCause} to create a Failure from a full Cause
272 *
273 * @category constructors
274 * @since 2.0.0
275 */
276export const fail: <E>(e: E) => Exit<never, E> = core.exitFail
277
278/**
279 * Creates a failed Exit from a defect (unexpected error).
280 *
281 * **When to use**
282 *
283 * Use when you need unexpected, unrecoverable errors that should not appear in
284 * the typed error channel.
285 *
286 * **Details**
287 *
288 * The defect is wrapped in a `Cause.Die` internally.
289 *
290 * Returns a `Failure<never>` with `E = never`, since defects do not appear in
291 * the typed error channel.
292 *
293 * **Example** (Creating a defect Exit)
294 *
295 * ```ts import.meta.vitest
296 * import { Exit } from "effect"
297 *
298 * Exit.die("Unexpected error") // => Exit.die("Unexpected error")
299 * ```
300 *
301 * @see {@link fail} to create a Failure from a typed error
302 * @see {@link hasDies} to check whether an Exit contains defects
303 *
304 * @category constructors
305 * @since 2.0.0
306 */
307export const die: (defect: unknown) => Exit<never> = core.exitDie
308
309/**
310 * Creates a failed Exit representing fiber interruption.
311 *
312 * **When to use**
313 *
314 * Use to signal that a fiber was interrupted.
315 *
316 * **Details**
317 *
318 * Optionally pass a fiber ID to identify which fiber was interrupted. Returns
319 * a `Failure<never>` with an `Interrupt` cause.
320 *
321 * **Example** (Creating an interruption Exit)
322 *
323 * ```ts import.meta.vitest
324 * import { Exit } from "effect"
325 *
326 * Exit.interrupt(123) // => Exit.interrupt(123)
327 * ```
328 *
329 * @see {@link hasInterrupts} to check whether an Exit contains interruptions
330 *
331 * @category constructors
332 * @since 2.0.0
333 */
334export const interrupt: (fiberId?: number | undefined) => Exit<never> = effect.exitInterrupt
335
336const void_: Exit<void> = effect.exitVoid
337export {
338 /**
339 * Provides a pre-allocated successful Exit with a `void` value.
340 *
341 * **When to use**
342 *
343 * Use when you need a shared successful `Exit` with no meaningful value.
344 *
345 * **Details**
346 *
347 * Equivalent to `Exit.succeed(undefined)` but shared as a single instance,
348 * avoiding allocation for a common case.
349 *
350 * **Example** (Referencing the void Exit)
351 *
352 * ```ts import.meta.vitest
353 * import { Exit } from "effect"
354 *
355 * Exit.void // => Exit.succeed(undefined)
356 * ```
357 *
358 * @see {@link succeed} to create a success with a specific value
359 * @see {@link asVoid} to discard the value of an existing Exit
360 *
361 * @category constructors
362 * @since 2.0.0
363 */
364 void_ as void
365}
366
367/**
368 * Checks whether an Exit is a Success.
369 *
370 * **When to use**
371 *
372 * Use as a type guard to narrow `Exit<A, E>` to `Success<A, E>` and access the
373 * `value` property.
374 *
375 * **Example** (Narrowing to success)
376 *
377 * ```ts import.meta.vitest
378 * import { Exit } from "effect"
379 *
380 * const exit = Exit.succeed(42)
381 *
382 * if (Exit.isSuccess(exit)) {
383 * exit.value // => 42
384 * }
385 * ```
386 *
387 * @see {@link isFailure} for the opposite check
388 * @see {@link match} for exhaustive pattern matching
389 *
390 * @category guards
391 * @since 2.0.0
392 */
393export const isSuccess: <A, E>(self: Exit<A, E>) => self is Success<A, E> = effect.exitIsSuccess
394
395/**
396 * Checks whether an Exit is a Failure.
397 *
398 * **When to use**
399 *
400 * Use as a type guard to narrow `Exit<A, E>` to `Failure<A, E>` and access the
401 * `cause` property.
402 *
403 * **Example** (Narrowing to failure)
404 *
405 * ```ts import.meta.vitest
406 * import { Cause, Exit } from "effect"
407 *
408 * const exit = Exit.fail("error")
409 *
410 * if (Exit.isFailure(exit)) {
411 * exit.cause // => Cause.fail("error")
412 * }
413 * ```
414 *
415 * @see {@link isSuccess} for the opposite check
416 * @see {@link match} for exhaustive pattern matching
417 *
418 * @category guards
419 * @since 2.0.0
420 */
421export const isFailure: <A, E>(self: Exit<A, E>) => self is Failure<A, E> = effect.exitIsFailure
422
423/**
424 * Checks whether a failed Exit contains typed errors (Fail reasons).
425 *
426 * **When to use**
427 *
428 * Use to distinguish typed failures from defects or interruptions.
429 *
430 * **Details**
431 *
432 * Returns `false` for successful exits. Only checks for `Fail` reasons in the
433 * Cause. A Cause with only `Die` or `Interrupt` reasons returns `false`.
434 *
435 * **Example** (Checking for typed errors)
436 *
437 * ```ts import.meta.vitest
438 * import { Exit } from "effect"
439 *
440 * Exit.hasFails(Exit.fail("err")) // => true
441 * Exit.hasFails(Exit.die("bug")) // => false
442 * Exit.hasFails(Exit.succeed(42)) // => false
443 * ```
444 *
445 * @see {@link hasDies} to check for defects
446 * @see {@link hasInterrupts} to check for interruptions
447 *
448 * @category guards
449 * @since 4.0.0
450 */
451export const hasFails: <A, E>(self: Exit<A, E>) => self is Failure<A, E> = effect.exitHasFails
452
453/**
454 * Checks whether a failed Exit contains defects (Die reasons).
455 *
456 * **When to use**
457 *
458 * Use to check whether an `Exit` failure cause contains unexpected errors.
459 *
460 * **Details**
461 *
462 * Returns `false` for successful exits. Only checks for `Die` reasons in the
463 * Cause. A Cause with only `Fail` or `Interrupt` reasons returns `false`.
464 *
465 * **Example** (Checking for defects)
466 *
467 * ```ts import.meta.vitest
468 * import { Exit } from "effect"
469 *
470 * Exit.hasDies(Exit.die("bug")) // => true
471 * Exit.hasDies(Exit.fail("err")) // => false
472 * Exit.hasDies(Exit.succeed(42)) // => false
473 * ```
474 *
475 * @see {@link hasFails} to check for typed errors
476 * @see {@link hasInterrupts} to check for interruptions
477 *
478 * @category guards
479 * @since 4.0.0
480 */
481export const hasDies: <A, E>(self: Exit<A, E>) => self is Failure<A, E> = effect.exitHasDies
482
483/**
484 * Checks whether a failed Exit contains interruptions (Interrupt reasons).
485 *
486 * **When to use**
487 *
488 * Use to check whether an `Exit` contains fiber interruption.
489 *
490 * **Details**
491 *
492 * Returns `false` for successful exits. Only checks for `Interrupt` reasons in
493 * the Cause. A Cause with only `Fail` or `Die` reasons returns `false`.
494 *
495 * **Example** (Checking for interruptions)
496 *
497 * ```ts import.meta.vitest
498 * import { Exit } from "effect"
499 *
500 * Exit.hasInterrupts(Exit.interrupt(1)) // => true
501 * Exit.hasInterrupts(Exit.fail("err")) // => false
502 * Exit.hasInterrupts(Exit.succeed(42)) // => false
503 * ```
504 *
505 * @see {@link hasFails} to check for typed errors
506 * @see {@link hasDies} to check for defects
507 *
508 * @category guards
509 * @since 4.0.0
510 */
511export const hasInterrupts: <A, E>(self: Exit<A, E>) => self is Failure<A, E> = effect.exitHasInterrupts
512
513/**
514 * Extracts the Success variant from an Exit as a Result.
515 *
516 * **When to use**
517 *
518 * Use when composing Exit checks with `Filter` or other `Result`-based
519 * filtering APIs and you want the full Success wrapper.
520 *
521 * **Details**
522 *
523 * Returns `Result.succeed(success)` when the Exit is a Success, or
524 * `Result.fail(failure)` with the original Failure otherwise.
525 *
526 * **Gotchas**
527 *
528 * This is not an `Option` accessor or an Effect failure. A failed extraction is
529 * represented as data in the `Result` failure channel.
530 *
531 * **Example** (Filtering for success)
532 *
533 * ```ts import.meta.vitest
534 * import { Exit, Result } from "effect"
535 *
536 * Exit.filterSuccess(Exit.succeed(42)) // => Result.succeed(Exit.succeed(42))
537 * ```
538 *
539 * @see {@link filterFailure} for the inverse
540 * @see {@link filterValue} to extract the raw value instead of the Success object
541 *
542 * @category filtering
543 * @since 4.0.0
544 */
545export const filterSuccess: <A, E>(
546 self: Exit<A, E>
547) => Result.Result<Success<A>, Failure<never, E>> = effect.exitFilterSuccess
548
549/**
550 * Extracts the success value from an Exit as a Result.
551 *
552 * **When to use**
553 *
554 * Use when composing Exit checks with `Filter` or other `Result`-based
555 * filtering APIs and you want the raw success value rather than the Success
556 * wrapper.
557 *
558 * **Details**
559 *
560 * Returns `Result.succeed(value)` when the Exit is a Success, or
561 * `Result.fail(failure)` with the original Failure otherwise.
562 *
563 * **Gotchas**
564 *
565 * This is not an `Option` accessor or an Effect failure. A failed extraction is
566 * represented as data in the `Result` failure channel.
567 *
568 * **Example** (Filtering for the value)
569 *
570 * ```ts import.meta.vitest
571 * import { Exit, Result } from "effect"
572 *
573 * Exit.filterValue(Exit.succeed(42)) // => Result.succeed(42)
574 * ```
575 *
576 * @see {@link filterSuccess} to get the full Success object
577 * @see {@link getSuccess} to get the value as an Option instead
578 *
579 * @category filtering
580 * @since 4.0.0
581 */
582export const filterValue: <A, E>(self: Exit<A, E>) => Result.Result<A, Failure<never, E>> = effect.exitFilterValue
583
584/**
585 * Extracts the Failure variant from an Exit as a Result.
586 *
587 * **When to use**
588 *
589 * Use when composing Exit checks with `Filter` or other `Result`-based
590 * filtering APIs and you want the full Failure wrapper.
591 *
592 * **Details**
593 *
594 * Returns `Result.succeed(failure)` when the Exit is a Failure, or
595 * `Result.fail(success)` with the original Success otherwise.
596 *
597 * **Gotchas**
598 *
599 * This is not an `Option` accessor or an Effect failure. A failed extraction is
600 * represented as data in the `Result` failure channel.
601 *
602 * **Example** (Filtering for failure)
603 *
604 * ```ts import.meta.vitest
605 * import { Exit, Result } from "effect"
606 *
607 * Exit.filterFailure(Exit.fail("err")) // => Result.succeed(Exit.fail("err"))
608 * ```
609 *
610 * @see {@link filterSuccess} for the inverse
611 * @see {@link filterCause} to extract the Cause directly
612 *
613 * @category filtering
614 * @since 4.0.0
615 */
616export const filterFailure: <A, E>(self: Exit<A, E>) => Result.Result<Failure<never, E>, Success<A>> =
617 effect.exitFilterFailure
618
619/**
620 * Extracts the Cause from a failed Exit as a Result.
621 *
622 * **When to use**
623 *
624 * Use when composing Exit checks with `Filter` or other `Result`-based
625 * filtering APIs and you want the raw Cause rather than the Failure wrapper.
626 *
627 * **Details**
628 *
629 * Returns `Result.succeed(cause)` when the Exit is a Failure, or
630 * `Result.fail(success)` with the original Success otherwise.
631 *
632 * **Gotchas**
633 *
634 * This is not an `Option` accessor or an Effect failure. A failed extraction is
635 * represented as data in the `Result` failure channel.
636 *
637 * **Example** (Filtering for the cause)
638 *
639 * ```ts import.meta.vitest
640 * import { Cause, Exit, Result } from "effect"
641 *
642 * Exit.filterCause(Exit.fail("err")) // => Result.succeed(Cause.fail("err"))
643 * ```
644 *
645 * @see {@link filterFailure} to get the full Failure object
646 * @see {@link getCause} to get the Cause as an Option instead
647 *
648 * @category filtering
649 * @since 4.0.0
650 */
651export const filterCause: <A, E>(self: Exit<A, E>) => Result.Result<Cause.Cause<E>, Success<A>> = effect.exitFilterCause
652
653/**
654 * Extracts the first typed error value from a failed Exit as a Result.
655 *
656 * **When to use**
657 *
658 * Use when you need the first typed error from an `Exit` as a `Result` for
659 * `Filter` or other `Result`-based filtering APIs.
660 *
661 * **Details**
662 *
663 * Returns `Result.succeed(error)` when the Cause contains a Fail reason, or
664 * `Result.fail(exit)` with the original Exit otherwise.
665 *
666 * **Gotchas**
667 *
668 * Only finds the first Fail reason. If the Cause has multiple errors, the rest
669 * are ignored.
670 *
671 * **Example** (Finding the first typed error)
672 *
673 * ```ts import.meta.vitest
674 * import { Exit, Result } from "effect"
675 *
676 * Exit.findError(Exit.fail("not found")) // => Result.succeed("not found")
677 * Exit.findError(Exit.die("bug")) // => Result.fail(Exit.die("bug"))
678 * ```
679 *
680 * @see {@link findErrorOption} to get the error as an Option instead
681 * @see {@link findDefect} to find defects instead
682 *
683 * @category filtering
684 * @since 4.0.0
685 */
686export const findError: <A, E>(input: Exit<A, E>) => Result.Result<E, Exit<A, E>> = effect.exitFindError
687
688/**
689 * Extracts the first defect from a failed Exit as a Result.
690 *
691 * **When to use**
692 *
693 * Use when you need the first defect from an `Exit` as a `Result` for
694 * `Filter` or other `Result`-based filtering APIs.
695 *
696 * **Details**
697 *
698 * Returns `Result.succeed(defect)` when the Cause contains a Die reason, or
699 * `Result.fail(exit)` with the original Exit otherwise.
700 *
701 * **Gotchas**
702 *
703 * Only finds the first Die reason. If the Cause has multiple defects, the rest
704 * are ignored.
705 *
706 * **Example** (Finding the first defect)
707 *
708 * ```ts import.meta.vitest
709 * import { Exit, Result } from "effect"
710 *
711 * Exit.findDefect(Exit.die("boom")) // => Result.succeed("boom")
712 * Exit.findDefect(Exit.fail("err")) // => Result.fail(Exit.fail("err"))
713 * ```
714 *
715 * @see {@link findError} to find typed errors instead
716 * @see {@link hasDies} to check for defects without extracting them
717 *
718 * @category filtering
719 * @since 4.0.0
720 */
721export const findDefect: <A, E>(input: Exit<A, E>) => Result.Result<unknown, Exit<A, E>> = effect.exitFindDefect
722
723/**
724 * Pattern matches on an Exit, handling both success and failure cases.
725 *
726 * **When to use**
727 *
728 * Use when you need exhaustive handling of both `Exit` success and failure
729 * outcomes.
730 *
731 * **Details**
732 *
733 * Calls `onSuccess` with the value if the Exit is a Success, and calls
734 * `onFailure` with the Cause if the Exit is a Failure.
735 *
736 * **Example** (Matching on an Exit)
737 *
738 * ```ts import.meta.vitest
739 * import { Exit } from "effect"
740 *
741 * Exit.match(Exit.succeed(42), {
742 * onSuccess: (value) => `Got: ${value}`,
743 * onFailure: () => "Failed"
744 * }) // => "Got: 42"
745 * ```
746 *
747 * @see {@link isSuccess} and {@link isFailure} for simple boolean checks
748 *
749 * @category pattern matching
750 * @since 2.0.0
751 */
752export const match: {
753 <A, E, X1, X2>(options: {
754 readonly onSuccess: (a: NoInfer<A>) => X1
755 readonly onFailure: (cause: Cause.Cause<NoInfer<E>>) => X2
756 }): (self: Exit<A, E>) => X1 | X2
757 <A, E, X1, X2>(
758 self: Exit<A, E>,
759 options: {
760 readonly onSuccess: (a: A) => X1
761 readonly onFailure: (cause: Cause.Cause<E>) => X2
762 }
763 ): X1 | X2
764} = effect.exitMatch
765
766/**
767 * Transforms the success value of an Exit using the given function.
768 *
769 * **When to use**
770 *
771 * Use to apply a transformation to the value inside a successful Exit
772 *
773 * **Details**
774 *
775 * Failures pass through unchanged.
776 *
777 * Allocates a new Exit if successful.
778 *
779 * **Example** (Mapping over a success)
780 *
781 * ```ts import.meta.vitest
782 * import { Exit } from "effect"
783 *
784 * Exit.map(Exit.succeed(21), (x) => x * 2) // => Exit.succeed(42)
785 * ```
786 *
787 * @see {@link mapError} to transform the error
788 * @see {@link mapBoth} to transform both success and error
789 *
790 * @category combinators
791 * @since 2.0.0
792 */
793export const map: {
794 <A, B>(f: (a: A) => B): <E>(self: Exit<A, E>) => Exit<B, E>
795 <A, E, B>(self: Exit<A, E>, f: (a: A) => B): Exit<B, E>
796} = effect.exitMap
797
798/**
799 * Transforms the typed error of a failed Exit using the given function.
800 *
801 * **When to use**
802 *
803 * Use to remap typed errors while preserving the Exit structure
804 *
805 * **Details**
806 *
807 * Successes pass through unchanged.
808 *
809 * Allocates a new Exit if the error is transformed.
810 *
811 * **Gotchas**
812 *
813 * Only transforms typed errors (Fail reasons). If the Cause contains only
814 * defects or interruptions, the failure passes through unchanged.
815 *
816 * **Example** (Mapping over an error)
817 *
818 * ```ts import.meta.vitest
819 * import { Exit } from "effect"
820 *
821 * Exit.mapError(Exit.fail("bad input"), (error) => error.toUpperCase()) // => Exit.fail("BAD INPUT")
822 * ```
823 *
824 * @see {@link map} to transform the success value
825 * @see {@link mapBoth} to transform both success and error
826 *
827 * @category combinators
828 * @since 2.0.0
829 */
830export const mapError: {
831 <E, E2>(f: (a: NoInfer<E>) => E2): <A>(self: Exit<A, E>) => Exit<A, E2>
832 <A, E, E2>(self: Exit<A, E>, f: (a: NoInfer<E>) => E2): Exit<A, E2>
833} = effect.exitMapError
834
835/**
836 * Transforms both the success value and typed error of an Exit.
837 *
838 * **When to use**
839 *
840 * Use when you need to remap both channels in one step.
841 *
842 * **Details**
843 *
844 * `onSuccess` transforms the value if the Exit is a Success. `onFailure`
845 * transforms the typed error if the Exit is a Failure with a Fail reason.
846 * Allocates a new Exit.
847 *
848 * **Gotchas**
849 *
850 * If the Cause contains only defects or interruptions, the failure passes
851 * through unchanged.
852 *
853 * **Example** (Mapping both channels)
854 *
855 * ```ts import.meta.vitest
856 * import { Exit } from "effect"
857 *
858 * Exit.mapBoth(Exit.succeed(42), {
859 * onSuccess: (x) => String(x),
860 * onFailure: (error: string) => error.toUpperCase()
861 * }) // => Exit.succeed("42")
862 * ```
863 *
864 * @see {@link map} to transform only the success value
865 * @see {@link mapError} to transform only the error
866 *
867 * @category combinators
868 * @since 2.0.0
869 */
870export const mapBoth: {
871 <E, E2, A, A2>(
872 options: { readonly onFailure: (e: E) => E2; readonly onSuccess: (a: A) => A2 }
873 ): (self: Exit<A, E>) => Exit<A2, E2>
874 <A, E, E2, A2>(
875 self: Exit<A, E>,
876 options: { readonly onFailure: (e: E) => E2; readonly onSuccess: (a: A) => A2 }
877 ): Exit<A2, E2>
878} = effect.exitMapBoth
879
880/**
881 * Discards the success value of an Exit, replacing it with `void`.
882 *
883 * **When to use**
884 *
885 * Use when you need to discard a successful `Exit` value while preserving
886 * whether the `Exit` succeeded or failed.
887 *
888 * **Details**
889 *
890 * Failures pass through unchanged.
891 *
892 * Allocates a new Exit if successful.
893 *
894 * **Example** (Discarding the success value)
895 *
896 * ```ts import.meta.vitest
897 * import { Exit } from "effect"
898 *
899 * Exit.asVoid(Exit.succeed(42)) // => Exit.succeed(undefined)
900 * ```
901 *
902 * @see {@link void_ void} for a pre-allocated void success
903 * @see {@link asVoidAll} to combine multiple exits into a single void Exit
904 *
905 * @category combinators
906 * @since 2.0.0
907 */
908export const asVoid: <A, E>(self: Exit<A, E>) => Exit<void, E> = effect.exitAsVoid
909
910/**
911 * Combines multiple Exit values into a single `Exit<void, E>`.
912 *
913 * **When to use**
914 *
915 * Use to validate that all exits in a collection succeeded
916 *
917 * **Details**
918 *
919 * If all exits are successful, this returns a void success. If any exit is a
920 * failure, this returns a single failure with all error causes combined.
921 *
922 * Iterates over the entire collection. Collects all failure causes, not just
923 * the first.
924 *
925 * **Example** (Combining exits)
926 *
927 * ```ts import.meta.vitest
928 * import { Exit } from "effect"
929 *
930 * Exit.asVoidAll([Exit.succeed(1), Exit.succeed(2), Exit.succeed(3)]) // => Exit.succeed(undefined)
931 * Exit.asVoidAll([Exit.succeed(1), Exit.fail("err"), Exit.succeed(3)]) // => Exit.fail("err")
932 * ```
933 *
934 * @see {@link asVoid} to discard the value of a single Exit
935 *
936 * @category combinators
937 * @since 4.0.0
938 */
939export const asVoidAll: <I extends Iterable<Exit<any, any>>>(
940 exits: I
941) => Exit<void, I extends Iterable<Exit<infer _A, infer _E>> ? _E : never> = effect.exitAsVoidAll
942
943/**
944 * Returns the success value of an Exit as an Option.
945 *
946 * **When to use**
947 *
948 * Use when you need the success value from an `Exit` as an `Option` instead of
949 * pattern matching.
950 *
951 * **Details**
952 *
953 * Returns `Option.some(value)` for a Success and `Option.none()` for a Failure.
954 *
955 * **Example** (Getting the success value)
956 *
957 * ```ts import.meta.vitest
958 * import { Exit, Option } from "effect"
959 *
960 * Exit.getSuccess(Exit.succeed(42)) // => Option.some(42)
961 * Exit.getSuccess(Exit.fail("err")) // => Option.none()
962 * ```
963 *
964 * @see {@link getCause} to extract the Cause of a failure
965 * @see {@link filterValue} for filter-pipeline usage
966 *
967 * @category getters
968 * @since 4.0.0
969 */
970export const getSuccess: <A, E>(self: Exit<A, E>) => Option<A> = effect.exitGetSuccess
971
972/**
973 * Returns the Cause of a failed Exit as an Option.
974 *
975 * **When to use**
976 *
977 * Use when you need the failure `Cause` from an `Exit` as an `Option` instead
978 * of pattern matching.
979 *
980 * **Details**
981 *
982 * Returns `Option.some(cause)` for a Failure and `Option.none()` for a Success.
983 *
984 * **Example** (Getting the failure cause)
985 *
986 * ```ts import.meta.vitest
987 * import { Cause, Exit, Option } from "effect"
988 *
989 * Exit.getCause(Exit.fail("err")) // => Option.some(Cause.fail("err"))
990 * Exit.getCause(Exit.succeed(42)) // => Option.none()
991 * ```
992 *
993 * @see {@link getSuccess} to extract the success value
994 * @see {@link filterCause} for filter-pipeline usage
995 *
996 * @category getters
997 * @since 4.0.0
998 */
999export const getCause: <A, E>(self: Exit<A, E>) => Option<Cause.Cause<E>> = effect.exitGetCause
1000
1001/**
1002 * Returns the first typed error from a failed Exit as an Option.
1003 *
1004 * **When to use**
1005 *
1006 * Use when you need the first typed error from an `Exit` as an `Option`,
1007 * ignoring successes and non-typed failures.
1008 *
1009 * **Details**
1010 *
1011 * Returns `Option.some(error)` if the Cause contains a Fail reason. Successes,
1012 * defect-only failures, and interrupt-only failures return `Option.none()`.
1013 *
1014 * **Gotchas**
1015 *
1016 * Only finds the first Fail reason. If the Cause has multiple typed errors,
1017 * the rest are ignored.
1018 *
1019 * **Example** (Getting the first error)
1020 *
1021 * ```ts import.meta.vitest
1022 * import { Exit, Option } from "effect"
1023 *
1024 * Exit.findErrorOption(Exit.fail("err")) // => Option.some("err")
1025 * Exit.findErrorOption(Exit.die("bug")) // => Option.none()
1026 * Exit.findErrorOption(Exit.succeed(42)) // => Option.none()
1027 * ```
1028 *
1029 * @see {@link findError} for filter-pipeline usage
1030 * @see {@link getCause} to get the full Cause as an Option
1031 *
1032 * @category getters
1033 * @since 4.0.0
1034 */
1035export const findErrorOption: <A, E>(self: Exit<A, E>) => Option<E> = effect.exitFindErrorOption