Skip to content

avoid_throw_in_fp_callback

v1.0.0WarningConfigurablefpdart

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).

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),
);

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.

analysis_options.yaml
many_lints:
rules:
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

This rule is in the core preset, so it is on with preset: core, preset: recommended or preset: opinionated.

To turn it off:

many_lints.yaml
rules:
avoid_throw_in_fp_callback: false

To keep the rule on but skip certain paths, use per-rule exclude.