This repository has been archived on 2026-06-02. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
FabledApp/lib/data/api/api_client.dart
T
bvandeusen c3d9cc273f fix: quick capture incorrectly treated as offline on LLM timeout
The global receiveTimeout is 30s but quick capture runs LLM inference
that can take much longer. receiveTimeout fired, fell through to the
NetworkException fallback in dioToApp, and the work queue queued it as
an offline item.

- quick_capture_api.dart: override receiveTimeout to 120s for the
  /api/quick-capture request
- api_client.dart: handle receiveTimeout/sendTimeout explicitly in the
  error interceptor, converting them to AppException (not NetworkException)
  so slow responses are never mistaken for being offline

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 07:54:00 -04:00

68 lines
2.2 KiB
Dart

import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import '../../core/exceptions.dart';
PersistCookieJar buildCookieJar(String cookiesPath) =>
PersistCookieJar(storage: FileStorage('$cookiesPath/.cookies/'));
Dio buildDio(String baseUrl, PersistCookieJar cookieJar) {
final dio = Dio(BaseOptions(
baseUrl: baseUrl,
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 30),
headers: {'Content-Type': 'application/json'},
));
dio.interceptors.add(CookieManager(cookieJar));
dio.interceptors.add(_ErrorInterceptor());
return dio;
}
class _ErrorInterceptor extends Interceptor {
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
if (err.response?.statusCode == 401) {
handler.reject(DioException(
requestOptions: err.requestOptions,
error: const AuthException('Session expired. Please log in again.'),
type: err.type,
response: err.response,
));
return;
}
if (err.type == DioExceptionType.connectionTimeout ||
err.type == DioExceptionType.connectionError) {
handler.reject(DioException(
requestOptions: err.requestOptions,
error: const NetworkException('Cannot reach server. Check your connection.'),
type: err.type,
response: err.response,
));
return;
}
if (err.type == DioExceptionType.receiveTimeout ||
err.type == DioExceptionType.sendTimeout) {
handler.reject(DioException(
requestOptions: err.requestOptions,
error: const AppException('Request timed out. The server is taking too long to respond.'),
type: err.type,
response: err.response,
));
return;
}
handler.next(err);
}
}
AppException dioToApp(DioException e) {
if (e.error is AppException) return e.error as AppException;
final status = e.response?.statusCode;
if (status == 401) return const AuthException('Not authenticated.');
if (status == 404) return const NotFoundException('Resource not found.');
return NetworkException(e.message ?? 'Unknown network error.');
}