avoid_throw_in_fp_callback
This rule flags a throw inside an fpdart Do body or inside a callback passed to one of fpdart’s chaining methods (map, flatMap, chainEither, mapLeft, andThen, alt, orElse).
Why use this rule
Section titled “Why use this rule”fpdart’s whole premise is that failure travels in the value — the Left of an Either, the None of an Option. That is what lets a caller handle every failure in one fold, and what makes the compiler enforce it.
A throw inside map or a Do body leaves that channel. It escapes the pipeline as an ordinary exception, so a caller that carefully folds every failure still crashes. Worse, the signature keeps promising otherwise: TaskEither<Failure, T> says the only failures are Failures.
This is one of four Do pitfalls that fpdart documents in its own do_constructor_pitfalls example.
See also: fpdart: Do notation, fpdart: Either
Option.Do(($) { if ($(testOption) == 'test') { throw Exception('Error'); } return 'success';});Option.Do(($) { final value = $(testOption); return $(value == 'test' ? Option<String>.none() : Option.of('success'));});In a TaskEither pipeline, map the thrown error into the left channel once, at the boundary:
TaskEither.tryCatch( () => api.load(), (error, stackTrace) => Failure.from(error),);Known limitations
Section titled “Known limitations”Throwing UnimplementedError, UnsupportedError, StateError or AssertionError is allowed by default. Those mark a branch that should never run — a programmer error, not a domain outcome — so routing them through the error channel would hand callers a Left they can neither handle nor meaningfully report. Set ignore_unimplemented: false to report them too.
Only fpdart’s own combinators are checked. A throw inside Iterable.map is ordinary Dart and is never reported.
Options
Section titled “Options”many_lints: rules: avoid_throw_in_fp_callback: ignore_unimplemented: false additional_methods: - traverserules: avoid_throw_in_fp_callback: ignore_unimplemented: false additional_methods: - traverse| Option | Type | Default | Description |
|---|---|---|---|
ignore_unimplemented |
bool | true |
Allow thrown UnimplementedError, UnsupportedError, StateError and AssertionError, which mark unreachable branches |
methods |
list of strings | the seven chaining methods | Replace the set of callback-taking methods that are checked |
additional_methods |
list of strings | [] |
Extend the set, for projects that wrap fpdart’s combinators in their own |
Configuration
Section titled “Configuration”This rule is in the core preset, so it is on with preset: core,
preset: recommended or preset: opinionated.
To turn it off:
rules: avoid_throw_in_fp_callback: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”avoid_get_or_else_swallowing_failure— getOrElse is handed the failure; ignoring it should be a visible decision.prefer_chain_either— chainEither lifts a synchronous Either step for you.avoid_ad_hoc_left_type— A pipeline only composes when every step shares one error type.avoid_bare_await_in_do— Awaiting a raw Future inside a Do block escapes the block’s tracking.