Sandboxing

On this page

Errors are a common part of programming, and they can happen for various reasons, such as failures, defects, fiber interruptions, or even a combination of these factors. In this guide, we'll explore how to use the Effect.sandbox function to isolate and understand the causes of errors in your code.

sandbox

The Effect.sandbox function is a valuable tool that allows you to encapsulate all the potential causes of an error in an effect. It exposes the full cause of an effect, whether it's due to a failure, defect, fiber interruption, or a combination of these factors.

Here's the signature of the Effect.sandbox function:

ts
sandbox: Effect<A, E, R> -> Effect<A, Cause<E>, R>
ts
sandbox: Effect<A, E, R> -> Effect<A, Cause<E>, R>

In simple terms, it takes an effect Effect<A, E, R> and transforms it into an effect Effect<A, Cause<E>, R> where the error channel now contains a detailed cause of the error.

By using the Effect.sandbox function, you gain access to the underlying causes of exceptional effects. These causes are represented as a type of Cause<E> and are available in the error channel of the Effect data type.

Once you have exposed the causes, you can utilize standard error-handling operators like Effect.catchAll and Effect.catchTags to handle errors more effectively. These operators allow you to respond to specific error conditions.

Let's walk through an example to illustrate how error sandboxing works:

ts
import { Effect, Console } from "effect"
 
const effect = Effect.fail("Oh uh!").pipe(Effect.as("primary result"))
 
const sandboxed = Effect.sandbox(effect)
 
const program = Effect.catchTags(sandboxed, {
Die: (cause) =>
Console.log(`Caught a defect: ${cause.defect}`).pipe(
Effect.as("fallback result on defect")
),
Interrupt: (cause) =>
Console.log(`Caught a defect: ${cause.fiberId}`).pipe(
Effect.as("fallback result on fiber interruption")
),
Fail: (cause) =>
Console.log(`Caught a defect: ${cause.error}`).pipe(
Effect.as("fallback result on failure")
)
})
 
const main = Effect.unsandbox(program)
 
Effect.runPromise(main).then(console.log)
/*
Output:
Caught a defect: Oh uh!
fallback result on failure
*/
ts
import { Effect, Console } from "effect"
 
const effect = Effect.fail("Oh uh!").pipe(Effect.as("primary result"))
 
const sandboxed = Effect.sandbox(effect)
 
const program = Effect.catchTags(sandboxed, {
Die: (cause) =>
Console.log(`Caught a defect: ${cause.defect}`).pipe(
Effect.as("fallback result on defect")
),
Interrupt: (cause) =>
Console.log(`Caught a defect: ${cause.fiberId}`).pipe(
Effect.as("fallback result on fiber interruption")
),
Fail: (cause) =>
Console.log(`Caught a defect: ${cause.error}`).pipe(
Effect.as("fallback result on failure")
)
})
 
const main = Effect.unsandbox(program)
 
Effect.runPromise(main).then(console.log)
/*
Output:
Caught a defect: Oh uh!
fallback result on failure
*/

In this example, we expose the full cause of an effect using Effect.sandbox. Then, we handle specific error conditions using Effect.catchTags. Finally, if needed, we can undo the sandboxing operation with Effect.unsandbox.