Add timeouts to the API calls

This commit is contained in:
Hank Grabowski 2023-05-09 16:42:53 -04:00
parent fbf95350e4
commit 97f48240b3
5 changed files with 51 additions and 22 deletions

View file

@ -1082,26 +1082,28 @@ abstract class FriendicaClient {
FutureResult<PagedResponse<List<dynamic>>, ExecError> _getApiListRequest( FutureResult<PagedResponse<List<dynamic>>, ExecError> _getApiListRequest(
Uri url) async { Uri url) async {
return (await getUrl(url, headers: _headers).andThenSuccessAsync( return await getUrl(url, headers: _headers).transformAsync(
(response) async => (response) async {
response.map((data) => jsonDecode(data) as List<dynamic>), return response.map((data) => jsonDecode(data) as List<dynamic>);
)) },
.mapError((error) => error as ExecError); ).execErrorCastAsync();
} }
FutureResult<PagedResponse<dynamic>, ExecError> _getApiPagedRequest( FutureResult<PagedResponse<dynamic>, ExecError> _getApiPagedRequest(
Uri url) async { Uri url) async {
return (await getUrl(url, headers: _headers).andThenSuccessAsync( return await getUrl(url, headers: _headers).transformAsync(
(response) async => response.map((data) => jsonDecode(data)), (response) async {
)) return response.map((data) => jsonDecode(data));
.mapError((error) => error as ExecError); },
).execErrorCastAsync();
} }
FutureResult<dynamic, ExecError> _getApiRequest(Uri url) async { FutureResult<dynamic, ExecError> _getApiRequest(Uri url) async {
return (await getUrl(url, headers: _headers).andThenSuccessAsync( return await getUrl(url, headers: _headers).transformAsync(
(response) async => jsonDecode(response.data), (response) async {
)) return jsonDecode(response.data);
.execErrorCastAsync(); },
).execErrorCastAsync();
} }
Map<String, String> get _headers => { Map<String, String> get _headers => {

View file

@ -22,6 +22,7 @@ const maxViewPortalWidth = 750.0;
const maxProcessingMillis = 3; const maxProcessingMillis = 3;
const processingSleep = Duration(milliseconds: 1); const processingSleep = Duration(milliseconds: 1);
const apiCallTimeout = Duration(seconds: 30);
Future<bool?> showConfirmDialog(BuildContext context, String caption) { Future<bool?> showConfirmDialog(BuildContext context, String caption) {
return showDialog<bool>( return showDialog<bool>(

View file

@ -56,7 +56,14 @@ extension ExecErrorExtension<T, E> on Result<T, E> {
? error ? error
: ExecError(type: ErrorType.localError, message: error.toString())); : ExecError(type: ErrorType.localError, message: error.toString()));
FutureResult<T, ExecError> execErrorCastAsync() async => execErrorCast(); FutureResult<T, ExecError> execErrorCastAsync() async {
return this.execErrorCast();
}
}
extension ExecErrorExtensionFuture<T, E> on FutureResult<T, E> {
FutureResult<T, ExecError> execErrorCastAsync() async =>
(await this).execErrorCast();
} }
void logError(ExecError error, Logger logger, void logError(ExecError error, Logger logger,

View file

@ -157,10 +157,6 @@ class AccountsService extends ChangeNotifier {
Future<void> setActiveProfile(Profile profile, Future<void> setActiveProfile(Profile profile,
{bool withNotification = true}) async { {bool withNotification = true}) async {
_currentProfile = profile; _currentProfile = profile;
Future.delayed(
const Duration(seconds: 10),
() async => await executeUpdatesForProfile(profile),
);
if (withNotification) { if (withNotification) {
notifyListeners(); notifyListeners();
} }

View file

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import '../globals.dart';
import 'package:result_monad/result_monad.dart'; import 'package:result_monad/result_monad.dart';
import '../friendica_client/paged_response.dart'; import '../friendica_client/paged_response.dart';
@ -9,17 +10,24 @@ import '../models/exec_error.dart';
final _logger = Logger('NetworkUtils'); final _logger = Logger('NetworkUtils');
http.Response requestTimeout() => http.Response('Client side timeout', 408);
FutureResult<PagedResponse<String>, ExecError> getUrl( FutureResult<PagedResponse<String>, ExecError> getUrl(
Uri url, { Uri url, {
Map<String, String>? headers, Map<String, String>? headers,
}) async { }) async {
_logger.finer('GET: $url'); _logger.finer('GET: $url');
try { try {
final response = await http.get( final request = http.get(
url, url,
headers: headers, headers: headers,
); );
final response = await request.timeout(
apiCallTimeout,
onTimeout: requestTimeout,
);
if (response.statusCode != 200) { if (response.statusCode != 200) {
return Result.error(ExecError( return Result.error(ExecError(
type: ErrorType.authentication, type: ErrorType.authentication,
@ -42,12 +50,17 @@ FutureResult<String, ExecError> postUrl(
}) async { }) async {
_logger.finer('POST: $url \n Body: $body'); _logger.finer('POST: $url \n Body: $body');
try { try {
final response = await http.post( final request = http.post(
url, url,
headers: headers, headers: headers,
body: jsonEncode(body), body: jsonEncode(body),
); );
final response = await request.timeout(
apiCallTimeout,
onTimeout: requestTimeout,
);
if (response.statusCode != 200) { if (response.statusCode != 200) {
return Result.error(ExecError( return Result.error(ExecError(
type: ErrorType.authentication, type: ErrorType.authentication,
@ -67,12 +80,17 @@ FutureResult<String, ExecError> putUrl(
}) async { }) async {
_logger.finer('PUT: $url \n Body: $body'); _logger.finer('PUT: $url \n Body: $body');
try { try {
final response = await http.put( final request = http.put(
url, url,
headers: headers, headers: headers,
body: jsonEncode(body), body: jsonEncode(body),
); );
final response = await request.timeout(
apiCallTimeout,
onTimeout: requestTimeout,
);
if (response.statusCode != 200) { if (response.statusCode != 200) {
return Result.error(ExecError( return Result.error(ExecError(
type: ErrorType.authentication, type: ErrorType.authentication,
@ -92,12 +110,17 @@ FutureResult<String, ExecError> deleteUrl(
}) async { }) async {
_logger.finer('DELETE: $url'); _logger.finer('DELETE: $url');
try { try {
final response = await http.delete( final request = http.delete(
url, url,
headers: headers, headers: headers,
body: jsonEncode(body), body: jsonEncode(body),
); );
final response = await request.timeout(
apiCallTimeout,
onTimeout: requestTimeout,
);
if (response.statusCode != 200) { if (response.statusCode != 200) {
return Result.error(ExecError( return Result.error(ExecError(
type: ErrorType.authentication, type: ErrorType.authentication,