import 'dart:io'; Future main(List arguments) async { final x1 = tryOrNull(() => throwing()); print(x1); final (v1, e1) = tryTuple(() => throwing()); print("$v1, $e1"); final (v2, e2) = tryTuple(() => nonThrowing()); print("$v2, $e2"); final x2 = await tryOrNullAsync(() => timeout(), Duration(seconds: 1)); print(x2); final (v3, e3) = await tryTupleAsync(() => timeout(), Duration(seconds: 1)); print("$v3, $e3"); final (v4, e4) = await tryTupleAsync(() => throwingAsync()); print("$v4, $e4"); final (v5, e5) = await tryTupleAsync(() => nonThrowingAsync()); print("$v5, $e5"); exit(0); } String throwing() { throw Exception('error message'); } String nonThrowing() { return "foo"; } Future timeout() async { await Future.delayed(Duration(minutes: 30)); return "foo"; } Future throwingAsync() async { await Future.delayed(Duration(milliseconds: 500)); throw Exception('error message'); } Future nonThrowingAsync() async { await Future.delayed(Duration(milliseconds: 500)); return "foo"; } T? tryOrNull(T Function() fn) { try { return fn(); } catch (_) { return null; } } Future tryOrNullAsync(Future Function() fn, [Duration timeout = const Duration(minutes: 1)]) async { try { final x = await fn().timeout(timeout); return x; } catch (_) { return null; } } (T?, Object?) tryTuple(T Function() fn) { try { return (fn(), null); } catch (e) { return (null, e); } } Future<(T?, Object?)> tryTupleAsync(Future Function() fn, [Duration timeout = const Duration(minutes: 1)]) async { try { final x = await fn().timeout(timeout); return (x, null); } catch (e) { return (null, e); } }