Guarantee Cleanup Even on Failure
Guideline
One of the key guarantees of Effect.acquireRelease and Effect.scoped is that the release effect runs regardless of whether the use phase succeeds, fails, or is interrupted. You never leave resources leaking.
Rationale
In traditional try/finally, if an exception occurs during cleanup or if the process is interrupted, the finally block might not run. Effect's bracket pattern ensures release is always invoked, even when the main logic fails or when a fiber is interrupted. This prevents resource leaks in production.
Good Example
import { Effect } from "effect"
const acquire = Effect.sync(() => ({ id: 1 }))
const release = () => Effect.log("Released!")
const program = Effect.acquireRelease(acquire, release).pipe(
Effect.flatMap(() => Effect.fail("oops")),
Effect.scoped
)
Effect.runPromise(program).catch(() => {})
// Logs: Released!
Explanation: Even though the use phase fails with Effect.fail("oops"), the release runs first. The error propagates after cleanup completes.
Anti-Pattern
Assuming cleanup will run only on success, or manually tracking resources and forgetting to close them on error paths.