๐ŸŽ“ A1Learner
๐Ÿ”
0 of 37 lessons completed

Dart Custom Exceptions

A custom exception is a class that implements Exception. It lets a program report its own kinds of problems.

A custom exception class

The class holds a message field. Its toString method builds the text that print shows.

class EmptyCartException implements Exception {
  final String message;

  EmptyCartException(this.message);

  @override
  String toString() {
    return 'EmptyCartException: $message';
  }
}

void main() {
  try {
    throw EmptyCartException('the cart has no items');
  } on EmptyCartException catch (e) {
    print(e);
  }
}

A function throws it on bad input

The checkout function throws when the cart is empty. A full cart skips the throw and prints its line.

class EmptyCartException implements Exception {
  final String message;

  EmptyCartException(this.message);

  @override
  String toString() {
    return 'EmptyCartException: $message';
  }
}

void checkout(List<String> cart) {
  if (cart.isEmpty) {
    throw EmptyCartException('checkout needs at least one item');
  }
  print('Checking out ${cart.length} items');
}

void main() {
  try {
    checkout([]);
  } on EmptyCartException catch (e) {
    print(e);
  }
  checkout(['apple', 'bread']);
}

The type name of the caught value

The first print shows the runtime type of the caught value. The second print shows its toString text.

class EmptyCartException implements Exception {
  final String message;

  EmptyCartException(this.message);

  @override
  String toString() {
    return 'EmptyCartException: $message';
  }
}

void main() {
  try {
    throw EmptyCartException('nothing to pay for');
  } on EmptyCartException catch (e) {
    print(e.runtimeType);
    print(e);
  }
}

A plain catch takes it too

A plain catch accepts any thrown value. The custom exception prints through it with the same toString text.

class EmptyCartException implements Exception {
  final String message;

  EmptyCartException(this.message);

  @override
  String toString() {
    return 'EmptyCartException: $message';
  }
}

void main() {
  try {
    throw EmptyCartException('empty again');
  } catch (e) {
    print(e);
  }
}

Example

class EmptyCartException implements Exception {
  final String message;

  EmptyCartException(this.message);

  @override
  String toString() {
    return 'EmptyCartException: $message';
  }
}

int totalPrice(List<int> prices) {
  if (prices.isEmpty) {
    throw EmptyCartException('add an item before paying');
  }
  var total = 0;
  for (var price in prices) {
    total += price;
  }
  return total;
}

void main() {
  print(totalPrice([4, 6]));
  try {
    print(totalPrice([]));
  } on EmptyCartException catch (e) {
    print(e);
  }
}

Key points

  • A custom exception is a class with implements Exception after its name.
  • A field stores extra detail about the problem.
  • A toString method decides what printing the exception shows.
  • An on clause can name the custom type and catch only that kind.
  • Printing e.runtimeType shows the name of the type that was thrown.

In this example, the first call adds the two prices and prints 10. The second call gets an empty list, so the guard throws the custom exception and the on clause prints its message.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท DartPad

Exercise

What does implements Exception do for a class?