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
- Fix 'Conditionally Branching Workflows' pattern to use Effect.filterOrFail
- Update examples from manual if statements to declarative filterOrFail
- Simplify predicates from Effect.Effect<boolean> to boolean
- Update all text references from Effect.filter to Effect.filterOrFail
- Fix API signature in guidelines to show Effect.filterOrFail(predicate, onFailure)
- Update 8 files across rules and content directories
Copy file name to clipboardExpand all lines: content/archived/conditionally-branching-workflows.mdx
+21-26Lines changed: 21 additions & 26 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,7 +26,7 @@ author: "effect_website"
26
26
## Guideline
27
27
28
28
To make decisions based on a successful value within an `Effect` pipeline, use predicate-based operators:
29
-
-**To Validate and Fail:** Use `Effect.filter(predicate)` to stop the workflow if a condition is not met.
29
+
-**To Validate and Fail:** Use `Effect.filterOrFail(predicate, onFailure)` to stop the workflow if a condition is not met.
30
30
-**To Choose a Path:** Use `Effect.if(condition, { onTrue, onFalse })` or `Effect.gen` to execute different effects based on a condition.
31
31
32
32
---
@@ -44,7 +44,7 @@ Using these operators turns conditional logic into a composable part of your `Ef
44
44
45
45
## Good Example: Validating a User
46
46
47
-
Here, we use `Effect.filter` with named predicates to validate a user before proceeding. The intent is crystal clear, and the business rules (`isActive`, `isAdmin`) are reusable.
47
+
Here, we use `Effect.filterOrFail` with named predicates to validate a user before proceeding. The intent is crystal clear, and the business rules (`isActive`, `isAdmin`) are reusable.
const program = (id:number):Effect.Effect<string, UserError> =>
71
-
Effect.gen(function* () {
72
-
// Find the user
73
-
const user =yield*findUser(id);
74
-
75
-
// Check if user is active
76
-
const active =yield*isActive(user);
77
-
if (!active) {
78
-
returnyield*Effect.fail("UserIsInactive"asconst);
79
-
}
80
-
81
-
// Check if user is admin
82
-
const admin =yield*isAdmin(user);
83
-
if (!admin) {
84
-
returnyield*Effect.fail("UserIsNotAdmin"asconst);
85
-
}
86
-
71
+
findUser(id).pipe(
72
+
// Validate user is active using Effect.filterOrFail
73
+
Effect.filterOrFail(
74
+
isActive,
75
+
() =>"UserIsInactive"asconst
76
+
),
77
+
// Validate user is admin using Effect.filterOrFail
78
+
Effect.filterOrFail(
79
+
isAdmin,
80
+
() =>"UserIsNotAdmin"asconst
81
+
),
87
82
// Success case
88
-
return`Welcome, admin user #${user.id}!`;
89
-
});
83
+
Effect.map((user) =>`Welcome, admin user #${user.id}!`)
84
+
);
90
85
91
86
// We can then handle the specific failures in a type-safe way.
92
87
const handled =program(123).pipe(
@@ -137,12 +132,12 @@ const program = (id: number) =>
137
132
Effect.map((u) =>`Welcome, ${u.name}!`),
138
133
);
139
134
140
-
// `Effect.filter` avoids this problem entirely by forcing a failure,
135
+
// `Effect.filterOrFail` avoids this problem entirely by forcing a failure,
141
136
// which keeps the success channel clean and correctly typed.
142
137
```
143
138
144
139
### Why This is Better
145
140
146
141
***It's a Real Bug:** This isn't just a style issue; it's a legitimate logical error that leads to incorrect types and broken code.
147
142
***It's a Common Mistake:** Developers new to functional pipelines often forget that every path must return a value.
148
-
***It Reinforces the "Why":** It perfectly demonstrates *why*`Effect.filter` is superior: `filter` guarantees that if the condition fails, the computation fails, preserving the integrity of the success channel.
143
+
***It Reinforces the "Why":** It perfectly demonstrates *why*`Effect.filterOrFail` is superior: `filterOrFail` guarantees that if the condition fails, the computation fails, preserving the integrity of the success channel.
Copy file name to clipboardExpand all lines: content/published/conditionally-branching-workflows.mdx
+21-26Lines changed: 21 additions & 26 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,7 +26,7 @@ author: "effect_website"
26
26
## Guideline
27
27
28
28
To make decisions based on a successful value within an `Effect` pipeline, use predicate-based operators:
29
-
-**To Validate and Fail:** Use `Effect.filter(predicate)` to stop the workflow if a condition is not met.
29
+
-**To Validate and Fail:** Use `Effect.filterOrFail(predicate, onFailure)` to stop the workflow if a condition is not met.
30
30
-**To Choose a Path:** Use `Effect.if(condition, { onTrue, onFalse })` or `Effect.gen` to execute different effects based on a condition.
31
31
32
32
---
@@ -44,7 +44,7 @@ Using these operators turns conditional logic into a composable part of your `Ef
44
44
45
45
## Good Example: Validating a User
46
46
47
-
Here, we use `Effect.filter` with named predicates to validate a user before proceeding. The intent is crystal clear, and the business rules (`isActive`, `isAdmin`) are reusable.
47
+
Here, we use `Effect.filterOrFail` with named predicates to validate a user before proceeding. The intent is crystal clear, and the business rules (`isActive`, `isAdmin`) are reusable.
const program = (id:number):Effect.Effect<string, UserError> =>
71
-
Effect.gen(function* () {
72
-
// Find the user
73
-
const user =yield*findUser(id);
74
-
75
-
// Check if user is active
76
-
const active =yield*isActive(user);
77
-
if (!active) {
78
-
returnyield*Effect.fail("UserIsInactive"asconst);
79
-
}
80
-
81
-
// Check if user is admin
82
-
const admin =yield*isAdmin(user);
83
-
if (!admin) {
84
-
returnyield*Effect.fail("UserIsNotAdmin"asconst);
85
-
}
86
-
71
+
findUser(id).pipe(
72
+
// Validate user is active using Effect.filterOrFail
73
+
Effect.filterOrFail(
74
+
isActive,
75
+
() =>"UserIsInactive"asconst
76
+
),
77
+
// Validate user is admin using Effect.filterOrFail
78
+
Effect.filterOrFail(
79
+
isAdmin,
80
+
() =>"UserIsNotAdmin"asconst
81
+
),
87
82
// Success case
88
-
return`Welcome, admin user #${user.id}!`;
89
-
});
83
+
Effect.map((user) =>`Welcome, admin user #${user.id}!`)
84
+
);
90
85
91
86
// We can then handle the specific failures in a type-safe way.
92
87
const handled =program(123).pipe(
@@ -143,12 +138,12 @@ const program = (id: number) =>
143
138
Effect.map((u) =>`Welcome, ${u.name}!`),
144
139
);
145
140
146
-
// `Effect.filter` avoids this problem entirely by forcing a failure,
141
+
// `Effect.filterOrFail` avoids this problem entirely by forcing a failure,
147
142
// which keeps the success channel clean and correctly typed.
148
143
```
149
144
150
145
### Why This is Better
151
146
152
147
***It's a Real Bug:** This isn't just a style issue; it's a legitimate logical error that leads to incorrect types and broken code.
153
148
***It's a Common Mistake:** Developers new to functional pipelines often forget that every path must return a value.
154
-
***It Reinforces the "Why":** It perfectly demonstrates *why*`Effect.filter` is superior: `filter` guarantees that if the condition fails, the computation fails, preserving the integrity of the success channel.
149
+
***It Reinforces the "Why":** It perfectly demonstrates *why*`Effect.filterOrFail` is superior: `filterOrFail` guarantees that if the condition fails, the computation fails, preserving the integrity of the success channel.
0 commit comments