timebox<T> function

Future<T> timebox<T>(
  1. Future<T> fn(),
  2. Duration timeout, {
  3. T? onTimeout,
})

Runs fn; if not completed in timeout, returns onTimeout result (or throws).

Implementation

Future<T> timebox<T>(Future<T> Function() fn, Duration timeout, {T? onTimeout}) async {
  final Completer<T> c = Completer<T>();
  Timer? t;
  t = Timer(timeout, () {
    if (!c.isCompleted) {
      if (onTimeout != null) {
        c.complete(onTimeout);
      } else {
        c.completeError(TimeboxException(_kTimeboxExceeded), StackTrace.current);
      }
    }
  });
  try {
    final T result = await fn();
    if (!c.isCompleted) c.complete(result);
    return await c.future;
  } on Object catch (e, st) {
    developer.log('Timebox caught error', name: 'timebox', error: e);
    if (!c.isCompleted) c.completeError(e, st);
    rethrow;
  } finally {
    t.cancel();
  }
}