Skip to content

avoid_nested_do_notation

v1.0.0 Warning fpdart

This rule flags an fpdart Do block written inside another Do block.

Each Do establishes its own extraction frame, and the inner block shadows the outer block’s $. An extraction that fails inside the inner body therefore short-circuits only the inner block: the outer block receives a perfectly ordinary None/Left as a value and carries on. The pipeline you meant to abort keeps running.

Do is sugar over flatMap, so a nested block is never necessary — the inner block’s steps can be extracted in the outer one directly.

This is one of four Do pitfalls that fpdart documents in its own do_constructor_pitfalls example. The others are avoid_throw_in_fp_callback, avoid_bare_await_in_do and avoid_dollar_outside_do_frame.

See also: fpdart: Do notation

Option.Do(($) => $(Option.Do(($) => $(testOption))));
Option.Do(($) => $(testOption));

With several steps, extract each one in the same frame:

TaskEither.Do(($) async {
final file = await $(fileAt(path));
final content = await $(readAsString(file));
return content;
});

The rule reports the inner block, which is the one to unwrap. In a three-level nest both inner blocks are reported, since each is separately wrong.

Sibling Do blocks in the same function are fine and are never reported — only lexical nesting matters.

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_nested_do_notation: false

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