Files
tatlock-ui/lib/core/api/api_client.dart
T
Jeroen SchweitzerandClaude Opus 4.5 34fdc77818
Build and Push / release (push) Successful in 4s
Build and Push / build (push) Successful in 2m58s
fix: prevent API client provider auto-dispose causing Ref invalidation
API client providers (coreApiClientProvider, tatlockApiClientProvider) now
use keepAlive: true. This fixes "DioException [unknown]: null" errors on
pages like /security/users where ref.read() was used without subscription.

The AuthInterceptor stores a Ref that became invalid when the provider
auto-disposed after a one-time read.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 20:08:46 +01:00

64 lines
1.7 KiB
Dart

import 'package:dio/dio.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:tatlock_ui/core/api/api_interceptors.dart';
import 'package:tatlock_ui/core/config/app_config.dart';
import 'api_client_native.dart' if (dart.library.html) 'api_client_web.dart'
as platform;
part 'api_client.g.dart';
/// Provides the Dio instance for Core API.
///
/// Uses keepAlive to prevent auto-dispose - the AuthInterceptor stores
/// a Ref that must remain valid for the lifetime of API requests.
@Riverpod(keepAlive: true)
Dio coreApiClient(Ref ref) {
final options = BaseOptions(
baseUrl: AppConfig.coreApiUrl,
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 30),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
);
final dio = platform.createDio(options);
dio.interceptors.addAll([
AuthInterceptor(ref),
LoggingInterceptor(),
ErrorInterceptor(),
]);
return dio;
}
/// Provides the Dio instance for Tatlock API.
///
/// Uses keepAlive to prevent auto-dispose - the AuthInterceptor stores
/// a Ref that must remain valid for the lifetime of API requests.
@Riverpod(keepAlive: true)
Dio tatlockApiClient(Ref ref) {
final options = BaseOptions(
baseUrl: AppConfig.tatlockApiUrl,
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(minutes: 5), // Longer for LLM responses
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
);
final dio = platform.createDio(options);
dio.interceptors.addAll([
AuthInterceptor(ref),
LoggingInterceptor(),
ErrorInterceptor(),
]);
return dio;
}