#flutter #dart
Вопрос:
У меня есть следующая функция кода Flutter amp; Dart, которая отправляет запрос на сервер:
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);
}
}
Обратите внимание, что URL-адрес намеренно неверен, поэтому время ожидания запроса истекает.
Но для этого я закодировал: .timeout(...)
по будущему запросу. Таким образом, в принципе, через 3 секунды он должен быть пойман с помощью on TimeoutException
исключения.
Это так и происходит. Однако примерно через 1 минуту (вероятно, какой-то тайм-аут http-запроса по умолчанию в dart) я получаю необнаруженное исключение, потому что время ожидания запроса истекло. Где я ошибаюсь?
Комментарии:
1. Вы не можете отменить a
Future
. Использование.timeout()
заставит aTimeoutException
быть выброшенным, если указанноеFuture
не завершится в течение отведенного времени, но это не помешает исходномуFuture
завершению в конечном итоге (успешно или с ошибкой).2. @jamesdlin В этом есть смысл. Итак, как я могу поймать эту ошибку?
Ответ №1:
Это потому, что вы используете его неправильно. .timeout
Код, который вы используете, — это общий тайм-аут на любое будущее. Таким образом, вы улавливаете ошибку будущего тайм-аута, но не улавливаете ошибку, возникающую из тайм-аута http-запроса.
Чтобы использовать его правильно, сначала добавьте следующий импорт: import 'package:http/io_client.dart' as http;
Затем измените код на:
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')!}',
});