All Projects → rrousselGit → Boundary

rrousselGit / Boundary

Licence: mit
Error Boundaries for Flutter

Programming Languages

dart
5743 projects

Warning, experimental project

Boundary

Boundary is a set of widgets that takes over FlutterError.onError and ErrorWidget.builder to make them composable and scoped.

If you found difficult to implement an "Oops"/Loading" screen or want explicit error reporting for only a specific subtree, then this library is for you.

Principle

Fallback UI are represented through one universal widget:

Boundary

This widget, when inserted inside the widget tree, is able to catch exceptions from descendants (and only descendants) to then create a fallback UI.

Here's a typical example:

Scaffold(
  appBar: AppBar(title: const Text('hello')),
  body: Boundary(
    fallbackBuilder: (context, error) {
      return const Center(child: Text('Oops'));
    },
    child: Container(
      color: Colors.red,
      padding: const EdgeInsets.all(50),
      child: Builder(builder: (_) {
        // a descendant somethow wants to abort the build
        return Defer(42);
      }),
    ),
  ),
);

Which renders the following:

screenshot

Notice how, even if there's a Container with padding and a red background as child of Boundary, the "Oops" screen doesn't show any of these:

The widget returned by fallbackBuilder is in an entirely different widget tree.

But the failing subtree (Container -> Builder) is not removed for the tree either! Its state is preserved and it is simply offstaged, until it rebuilds successfuly.

This is proved by the following example, which shows how Boundary can be used to show a loading/error screen from a FutureBuilder deeper in the widget tree – without having a reference on the Future.

Boundary(
  fallbackBuilder: (_, error) {
    // doesn't have the reference on the Future, but
    // is still able to display loading/error state
    if (error is Loading) {
      return const Center(child: CircularProgressIndicator());
    } else if (error is NotFoundError) {
      return const NotFoundScreen();
    } else {
      return const OopsScreen();
    }
  },
  child: SubtreeThatHasAFutureBuilder(),
)

future builder example

FAQ

How to remove the fallback screen

Once an exception is thrown, the fallback screen is shown. But you may want to stop showing that fallback at some point.

To achieve this, simply rebuild the failling widget such that it doesn't throw anymore. This will automatically remove the fallback screen.

What happens if there's an exception inside fallbackBuilder?

If there's an exception inside fallbackBuilder, then the exception is propagated to the next Boundary, until there are none anymore.

Boundary(
  fallbackBuilder: (_, err) => Text(err.toString()),
  child: Boundary(
    fallbackBuilder: (_, err) {
      print(err);
      return Defer(err);
    },
    child: Builder(builder: (_) {
      return Defer(42);
    })
  )
)

Using the previous snippet, this will first print 42 in the console, then render a Text with "42" on screen.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].