You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Handle Your First Error with Effect.fail and catchAll
id
getting-started-handle-errors
skillLevel
beginner
applicationPatternId
getting-started
lessonOrder
4
summary
Learn how to create Effects that can fail and how to recover from those failures using Effect.fail and Effect.catchAll.
tags
getting-started
error-handling
fail
catchAll
beginner
rule
description
Handle errors with Effect.fail and catchAll.
related
getting-started-hello-world
combinator-error-handling
error-handling-pattern-accumulation
author
Paul Philp
Handle Your First Error with Effect.fail and catchAll
Guideline
Use Effect.fail to create an Effect that fails with an error, and
Effect.catchAll to recover from that failure.
Rationale
Real programs fail. Effect makes failures explicit in the type system so you
can't forget to handle them. Unlike try/catch, Effect errors are tracked in
types.
Creating a Failing Effect
import{Effect}from"effect";// An Effect that always failsconstalwaysFails=Effect.fail("Something went wrong");// An Effect that might fail based on a conditionconstdivide=(a: number,b: number)=>b===0
? Effect.fail("Cannot divide by zero")
: Effect.succeed(a/b);
Recovering from Errors
import{Effect,pipe}from"effect";constdivide=(a: number,b: number)=>b===0
? Effect.fail("Division by zero")
: Effect.succeed(a/b);// Without error handling - this would failconstunsafeResult=divide(10,0);// With error handling - recover with a default valueconstsafeResult=pipe(divide(10,0),Effect.catchAll((error)=>{console.log(`Caught error: ${error}`);returnEffect.succeed(0);// Return 0 as fallback}));Effect.runSync(safeResult);// 0
Using Typed Errors
import{Effect,pipe}from"effect";// Define specific error typesclassDivisionByZero{readonly_tag="DivisionByZero";}classNegativeNumber{readonly_tag="NegativeNumber";constructor(readonlyvalue: number){}}// Function with typed errorsconstsafeDivide=(a: number,b: number): Effect.Effect<number,DivisionByZero|NegativeNumber>=>{if(b===0)returnEffect.fail(newDivisionByZero());if(a<0)returnEffect.fail(newNegativeNumber(a));returnEffect.succeed(a/b);};// Handle all errorsconstresult=pipe(safeDivide(-10,2),Effect.catchAll((error)=>{switch(error._tag){case"DivisionByZero":
returnEffect.succeed(0);case"NegativeNumber":
returnEffect.succeed(Math.abs(error.value));}}));