eslint-plugin-total-functions
eslint-plugin-total-functions copied to clipboard
New rule: detect premature logging in fp-ts code
Some codebases will have embraced TaskEither and friends but will not have adopted a hard-line stance against impure logging.
In these codebases, imperative logging is tolerated. Fine you might say, but it does open us up to the antipattern of premature logging -- logging that happens during program construction when it should actually happen during program execution.
Here's an example:
const launch = (numberToLaunch: number): TaskEither<never, string> => {
// This logging is premature. This is the line that would be flagged by the proposed rule.
// The author believed they were logging during program execution but they are actually logging during program construction.
console.info(`Launching ${numberToLaunch} nukes!`);
// TE.of is just for illustration here. It could be an HTTP call or any other impure operation
// and the effect type doesn't have to be TE (it could be IO, RTE, etc).
return TE.of(`${numberToLaunch} nukes launched`);
};
// This returns an effect but doesn't interpret (execute) it.
const launchSevenNukes = launch(7);
// At this point, the logs say "Launching 7 nukes" but no such operation has actually started!
// It is only after we interpret the effect that the actual nuke launching operation has started.
const launchNukesPromise = launchSevenNukes();
// Here is the first moment we should actually see logs.
// And here is the actual result of launching.
const result = await launchNukesPromise;
If we construct the effect and then:
- defer execution to much later in the program
- decide not to actually execute it
- execute it multiple times (e.g. to implement retries) ... then the logs are going to be misleading to one degree or another.