checked_exceptions 1.0.1
checked_exceptions: ^1.0.1 copied to clipboard
Checked exceptions for Dart, as an analyzer plugin. A call to a @Throws-annotated function must be caught or propagated, and a catch clause must not silently swallow it.
Changelog #
All notable changes to this package are recorded here. Versions follow semver. A new diagnostic, or a new SDK table entry, is a minor bump rather than a patch, because either can fail a build that passed before.
1.0.1 #
Lowers the minimum Dart SDK from 3.13.2 to 3.11.0. Nothing else changed: every dependency already resolved on 3.11, so the old constraint kept consumers off earlier stable SDKs for no reason.
1.0.0 #
First release.
Checked exceptions for Dart, as an analyzer plugin. Declare what a function throws and the analyzer holds callers to it.
class ConfigError implements Exception {}
@Throws({ConfigError})
String loadConfig(String path) => /* ... */;
String read(String path) {
return loadConfig(path); // unhandled_throws
}
Two rules, which only make sense together:
-
unhandled_throwsreports a call whose declared exceptions are neither caught at the call site nor re-declared on the enclosing function. Satisfy it by catching the exception, or by propagating it with@Throwsand pushing the decision to your caller. -
empty_catchreports acatchclause that swallows what it caught: the body is empty, nothing is rethrown, and the exception is never used. A comment inside the braces clears it, which is the documented way to say the silence is deliberate.This ships alongside the first rule rather than separately because an empty
catchis the cheapest way to silenceunhandled_throwswithout handling anything. A release with one and not the other would reward exactly the code it exists to prevent.
A quick fix propagates an unhandled exception by annotating the enclosing function, so the common resolution is one keystroke in the IDE.
A curated table of 141 Dart and Flutter members known to throw is treated as
if those members carried @Throws, so int.parse, File.readAsString and
jsonDecode are covered without annotating the SDK.
tool/verify_sdk_table.dart resolves every entry against the real SDKs, because
an entry naming a member that does not exist would fail silently: no test breaks,
the lint simply never fires for it.
@Throws is identified by its declaring package, so a same-named annotation from
somewhere else cannot drive these rules.
Diagnostics are suppressed the usual way, with the plugin name as a prefix:
// ignore: checked_exceptions/unhandled_throws
If you used these rules inside arxdeus_lints #
They shipped there once, alongside rules about object lifetimes and secrets.
Checked exceptions are a self-contained idea with their own annotation, so a
project that wants @Throws no longer has to take missing_dispose with it.
To migrate: add checked_exceptions to dependencies and to the plugins
section of analysis_options.yaml, import @Throws from
package:checked_exceptions/checked_exceptions.dart, and change any
// ignore: arxdeus_lints/unhandled_throws or empty_catch comment to the
checked_exceptions/ prefix. The diagnostics themselves are identical.