fix: add 30s timeout to API calls and catchError fallback on schedule load

Without a timeout, a hanging backend request left the schedule page showing
an infinite spinner forever. Timeout ensures any hung request fails fast and
the spinner resolves. The catchError fallback in schedule_view handles the
edge case where getProfessional rejects unexpectedly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-12 17:42:43 -05:00
co-authored by Claude Sonnet 4.6
parent dbeda22e19
commit 360f88777b
2 changed files with 9 additions and 4 deletions
+6 -4
View File
@@ -30,8 +30,10 @@ class ApiService {
throw Exception(body['message'] ?? 'Error ${res.statusCode}'); throw Exception(body['message'] ?? 'Error ${res.statusCode}');
} }
static const _timeout = Duration(seconds: 30);
Future<dynamic> get(String path) async { Future<dynamic> get(String path) async {
final res = await http.get(Uri.parse('$baseUrl$path'), headers: await _headers()); final res = await http.get(Uri.parse('$baseUrl$path'), headers: await _headers()).timeout(_timeout);
return _parse(res); return _parse(res);
} }
@@ -40,7 +42,7 @@ class ApiService {
Uri.parse('$baseUrl$path'), Uri.parse('$baseUrl$path'),
headers: await _headers(), headers: await _headers(),
body: jsonEncode(body), body: jsonEncode(body),
); ).timeout(_timeout);
return _parse(res); return _parse(res);
} }
@@ -49,12 +51,12 @@ class ApiService {
Uri.parse('$baseUrl$path'), Uri.parse('$baseUrl$path'),
headers: await _headers(), headers: await _headers(),
body: jsonEncode(body), body: jsonEncode(body),
); ).timeout(_timeout);
return _parse(res); return _parse(res);
} }
Future<dynamic> delete(String path) async { Future<dynamic> delete(String path) async {
final res = await http.delete(Uri.parse('$baseUrl$path'), headers: await _headers()); final res = await http.delete(Uri.parse('$baseUrl$path'), headers: await _headers()).timeout(_timeout);
return _parse(res); return _parse(res);
} }
+3
View File
@@ -1,3 +1,4 @@
import 'package:prosapp_web_app/models/profesional.dart';
import 'package:prosapp_web_app/models/usuario.dart'; import 'package:prosapp_web_app/models/usuario.dart';
import 'package:prosapp_web_app/providers/auth_provider.dart'; import 'package:prosapp_web_app/providers/auth_provider.dart';
import 'package:prosapp_web_app/providers/professional_form_provider.dart'; import 'package:prosapp_web_app/providers/professional_form_provider.dart';
@@ -39,6 +40,8 @@ class _ScheduleViewState extends State<ScheduleView> {
professionalFormProvider.clear(); professionalFormProvider.clear();
proProvider.getProfessional(authProvider.user!.id).then((value) { proProvider.getProfessional(authProvider.user!.id).then((value) {
professionalFormProvider.setProfesional(value); professionalFormProvider.setProfesional(value);
}).catchError((_) {
professionalFormProvider.setProfesional(Profesional.empty());
}); });
profileFormProvider.user = authProvider.user; profileFormProvider.user = authProvider.user;