Home > Enterprise >  Why sending the following request ends up with uncaught exception?
Why sending the following request ends up with uncaught exception?

Time:10-24

I have the following Flutter & Dart code function, which sends a request to the server:

Future<void> autoAuth(BuildContext ctx) async {
  final url = Uri.parse('${this._baseURL.toString()}/auto-auth');

  try {
    final deviceStorage = await SharedPreferences.getInstance();

    if (deviceStorage.getString('refreshToken') == null) {
      return this._setUser(null);
    }

    final response = await http.post(url, headers: {
      'Authorization': 'Bearer ${deviceStorage.getString('refreshToken')!}',
    }).timeout(const Duration(seconds: 3));
    final Map<String, dynamic> responseBody = json.decode(response.body);

    if (responseBody['success']) {
      this._refreshAccessToken(ctx, deviceStorage);

      return this._setUser(new User(
        id: responseBody['data']['id'],
        isSubscribed: responseBody['data']['isSubscribed'],
        playlistId: responseBody['data']['playlistId'],
      ));
    }

    this._setUser(null);
  } on SocketException {
    this._setUser(null);

    throw Error();
  } on TimeoutException {
    this._setUser(null);

    throw Error();
  } catch (_) {
    this._setUser(null);
  }
}

Note, that url is wrong intentionally, so the request will timeout. But, for this, I coded: .timeout(...) on the future request. So, basically, after 3 secnods it should caught by on TimeoutException exception catch.

It does so. However, after something like 1 minute (probably some default timeout of http request in dart), I get an uncaught exception because the request has timed-out. Where Am I wrong?

CodePudding user response:

This is because you are using it in the wrong way. The .timeout code you use, is generic timeout for any future. Thus, you catch the error of the future timeout, but you don't catch the error being generated from the http request timeout.

To use it correctly, first add the following import: import 'package:http/io_client.dart' as http;

Then change the code to:

final ioClient = HttpClient();
ioClient.connectionTimeout = const Duration(seconds: 3);
final client = http.IOClient(ioClient);

final response = await client.post(url, headers: {
  'Authorization': 'Bearer ${deviceStorage.getString('refreshToken')!}',
});
  • Related