Suppress and refactor safely
The three @antithrow/* rules report different problems, and their "easy suppression" is the wrong answer each time. Here is the right one.
no-unsafe-unwrap — don't silence, split
When you see the rule fire on .unwrap():
const config = readConfig().unwrap(); // reports unsafeUnwrap
Don't disable it. Branch:
const result = readConfig();
if (result.isErr()) return exitWithError(result.error);
const config = result.value;
The rule auto-fixes .unwrap() / .unwrapErr() to .value / .error only when the type is statically Ok / Err. If the fix didn't apply, the rule couldn't prove safety — handle the failure yourself.
no-unused-result — don't void, handle
The suggestion to prepend void exists for the rare case where you legitimately want to fire-and-forget:
void logAsync(payload); // ok — we don't wait, we don't care about failure
But most hits are genuinely missing handling. Prefer:
const logged = await logAsync(payload);
if (logged.isErr()) metrics.increment("log_failure");
Use void only when you would never have read the return value even with exceptions.
no-throwing-call — replace, don't disable
See Enforce no-throwing-call. The intended fix is a different import.
Refactor order
When opting a legacy file in:
- Turn the rules on at
warn. - Fix
no-throwing-callfirst (import swap, zero control-flow change). - Fix
no-unsafe-unwrapby branching — this is the real work. - Fix
no-unused-resultlast — often the other two surface the real handler and the unused warnings vanish naturally. - Upgrade the rules to
error.
See also
- Reference:
no-throwing-call·no-unsafe-unwrap·no-unused-result - How-to: Migrate from throwing code