throws 1.0.0 copy "throws: ^1.0.0" to clipboard
throws: ^1.0.0 copied to clipboard

An annotation for documenting and enforcing throwing functions.

throws #

add_throws try_catch

Annotations for documenting and enforcing throwing functions.

This package is the annotation layer. It works with:

  • throws_plugin: analyzer plugin that enforces annotations and call handling.
  • throws_collector: optional heuristic tool that can generate maps for external APIs to improve plugin accuracy.

Install #

Add the dependency to your pubspec.yaml.

Usage #

Annotate functions that can throw:

@Throws(reason: 'Parsing input failed', errors: {FormatException, RangeError})
int parsePositiveInt(String input) {
  final value = int.parse(input);
  if (value < 0) {
    throw RangeError('Value must be non-negative');
  }
  return value;
}

You can also use the shorthand constant:

@throws
void mightThrow() {
  throw Exception('x');
}

Expected errors #

Use errors to declare the error types callers should handle. This is a set of Type literals.

@Throws(reason: 'Reason', errors: {StateError})
int singleValue(Iterable<int> values) => values.single;

Examples #

Missing annotation #

Bad (missing @Throws):

int parsePositiveInt(String input) {
  final value = int.parse(input);
  if (value < 0) {
    throw RangeError('Value must be non-negative');
  }
  return value;
}

Good:

@Throws(reason: 'Parsing input failed', errors: {RangeError})
int parsePositiveInt(String input) {
  final value = int.parse(input);
  if (value < 0) {
    throw RangeError('Value must be non-negative');
  }
  return value;
}

Calling a throwing function without handling #

Bad (no try/catch and no @Throws on caller):

@Throws(reason: 'May throw', errors: {StateError})
int singleValue(Iterable<int> values) => values.single;

int readOne(Iterable<int> values) {
  return singleValue(values);
}

Good (handle it):

@Throws(reason: 'May throw', errors: {StateError})
int singleValue(Iterable<int> values) => values.single;

int readOne(Iterable<int> values) {
  try {
    return singleValue(values);
  } on StateError {
    return -1;
  }
}

Good (or declare it):

@Throws(reason: 'May throw', errors: {StateError})
int singleValue(Iterable<int> values) => values.single;

@Throws(reason: 'Pass-through', errors: {StateError})
int readOne(Iterable<int> values) => singleValue(values);

Annotation mismatch #

Bad (declared errors do not match):

@Throws(reason: 'Wrong error set', errors: {ArgumentError})
void risky() {
  throw StateError('boom');
}

Good:

@Throws(reason: 'Right error set', errors: {StateError})
void risky() {
  throw StateError('boom');
}

How it all works together #

  1. You annotate functions with @Throws or @throws.
  2. throws_plugin inspects your code and:
    • Requires annotations on functions that throw.
    • Requires try/catch or annotations when calling throwing functions.
    • Validates that declared errors match what is thrown.
  3. throws_plugin can also read a throws.yaml file at your package root to learn about throwing members outside your package (SDK or dependencies).
  4. throws_collector can generate those maps, but it is optional and best-effort.

This package does not perform analysis itself. It only provides the annotations and shared types for the plugin.

3
likes
160
points
402
downloads
screenshot

Publisher

verified publisherfeduke-nukem.dev

Weekly Downloads

An annotation for documenting and enforcing throwing functions.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

More

Packages that depend on throws