Dart - Set & Handle Future Timeout Examples

In this tutorial, I am going to show you how to set and handle timeout when using Future in Dart (including any framework such as Flutter).

Future is usually used in Dart to handle asynchronous tasks. An asynchronous task takes time to finish. Sometimes, it can take longer than expected. In that case, we may need to handle the execution so that the process or the user doesn't wait too long. Fortunately, Dart's Future already has that functionality. Below you can see the examples of how to set timeout and handle TimeoutException.

Set Timeout

For example, we have a function that returns a Future. To make it easy to simulate timeout, we add a fixed 5 second delay before returning the value.

  Future<String> fetchValue() async {
    await Future.delayed(Duration(seconds: 5));
    print('done');
    return Future.value('my_value');
  }

Future already has a method named timeout. It can be used to time-out the Future after a given time limit has passed.

  Future<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()?})

It has one required positional argument where you need to pass a Duration instance as the time limit. There is also an optional named argument onTimeout which will be explained later. The method itself returns a new Future that completes with the same value as this Future unless it cannot complete in time.

  String value = await fetchValue()
      .timeout(Duration(seconds: 3));

If the Future doesn't complete or error after the time limit has passed, it will throw a TimeoutException.

  Unhandled exception:
  TimeoutException after 0:00:03.000000: Future not completed

Handling TimeoutException

The exception can be handled by using the conventional try catch block.

  try {
    final value = await fetchValue()
        .timeout(Duration(seconds: 3));
    print('value: $value');
  } catch (err) {
    print(err);
  }

Another way to handle timeout is by passing a function as the onTimeout named argument. It will be used as a fallback to return a value when the time limit has passed.

  await fetchValue()
      .timeout(
        Duration(seconds: 3),
        onTimeout: () {
          // Handle timeout here
          return 'timeout';
        }
      );

In this example, if the error is caught or handled properly, you'll find out that the 'done' text is printed even when the execution exceeds the time limit. That means the Future actually still runs and is not canceled after the time limit has passed.

Summary

You can set a timeout to a Dart's Future by using Future's timeout method. If the Future doesn't complete after the given time limit, it will throw a TimeoutException. You can either catch the error or pass onTimeout callback to return a value when timeout occurs. Keep in mind that timeout is only used to handle the code execution so that it doesn't wait too long. It doesn't cancel the Future itself.