Networking & Interceptors
Relevant source files
The following files were used as context for generating this wiki page:
The Networking and Interceptor system in MoodTune provides a robust, layered architecture for handling HTTP communication between the Flutter mobile application and external services, primarily the FastAPI backend and Supabase. It is designed to handle automated authentication, error tracking, and structured logging through a centralized ApiClient utilizing the Dio package.
This system ensures that all requests are securely authenticated, failed requests due to expired sessions are transparently retried, and network-related issues are caught and reported consistently across the application.
Core Networking Architecture
MoodTune utilizes a Clean Architecture approach where the Data Layer contains RemoteDataSources that interact directly with the ApiClient. The networking stack is composed of multiple specialized interceptors that process outgoing requests and incoming responses.
The diagram shows the request flow from a Data Source through the chain of interceptors to the external API.
Sources: CLAUDE.md:73-86, authplan.md:70-85
Key Components
| Component | Responsibility | File Path |
|---|---|---|
| ApiClient | High-level wrapper for Dio providing standard HTTP methods and configuration. | lib/core/network/api_client.dart |
| AuthInterceptor | Injects Bearer tokens into headers and handles 401 Unauthorized retries. | lib/core/network/interceptors/auth_interceptor.dart |
| TokenStorage | Securely stores and retrieves JWTs using FlutterSecureStorage with chunking. | lib/core/network/token_storage.dart |
| TalkerDioLogger | Provides structured, color-coded logging for all network activity. | lib/core/network/logging/talker.dart |
| SentryDio | Captures network exceptions and reports them to Sentry for monitoring. | lib/core/network/network/sentry_dio.dart |
Sources: authplan.md:50-100, CLAUDE.md:120-130
Authentication & Token Management
The AuthInterceptor is the most critical component of the networking stack. It facilitates transparent session management by interacting with TokenStorage and the Supabase client.
Token Injection and Refresh Flow
- Request Stage: The
AuthInterceptorretrieves the current token fromTokenStorage. If available, it adds theAuthorization: Bearer <token>header to the request. - Response Stage: If the server returns a
401 Unauthorizedstatus, the interceptor intercepts the error. - Refresh Stage: The interceptor attempts to refresh the Supabase session.
- Retry Stage: If the refresh is successful, the new token is stored, and the original request is retried with the updated header.
Sequence diagram illustrating the 401 Unauthorized recovery flow handled by the interceptor.
Sources: authplan.md:92-110, CLAUDE.md:83-86
Secure Storage (TokenStorage)
To handle security and platform limitations, TokenStorage implements specific logic for JWT persistence:
- Chunking: Tokens exceeding 3500 characters are split into smaller segments (3000 chars each) to bypass storage limits on certain platforms.
- Metadata: It maintains
token_storage_typeto track if a token was stored as a single string or in chunks.
Sources: authplan.md:50-68
Data Source Configurations
Different features within MoodTune require varied networking configurations, specifically regarding timeouts and content types.
Specific Datasource Settings
- AnalysisRemoteDataSource: Handles standard API interactions for mood history and track metadata.
- AudioUploadRemoteDataSource: Configured with extended timeouts to accommodate large file uploads (up to 15MB).
- Connect Timeout: 30 seconds.
- Receive/Send Timeout: 90 seconds.
- SpotifyRepositoryImpl: Interacts with Spotify OAuth and profile endpoints.
Sources: CLAUDE.md:130-145, README.md:16-20
Environment Configuration
Networking behavior is determined by environment variables passed during build time:
# Examples of networking env variables
API_BASE_URL: https://moodtune-backend-production.up.railway.app/api/v1
SUPABASE_URL: https://xyz.supabase.co
SENTRY_DSN: https://public@sentry.io/123
Sources: CLAUDE.md:152-162, pubspec.yaml:22-24
Error Handling and Logging
The system converts low-level networking exceptions into high-level Domain Failures to be consumed by the Presentation layer.
Exception Mapping
Networking errors caught by Dio or the ErrorInterceptor are mapped as follows:
- NetworkFailure: Used when there is no active internet connection (verified via
InternetConnectionChecker). - ServerException: Thrown by DataSources when the backend returns a non-200 status code not handled by
AuthInterceptor. - AuthFailure: Specifically for failures during the login, registration, or session refresh process.
// Example of the ResultFuture pattern used in networking
typedef ResultFuture<T> = Future<Either<Failure, T>>;
// Implementation in a Repository
try {
final result = await remoteDataSource.analyzeTrack(id);
return Right(result);
} on ServerException catch (e) {
return Left(ServerFailure(message: e.message));
}
Sources: CLAUDE.md:100-115, authplan.md:165-175
Summary
The Networking & Interceptor system in MoodTune serves as a centralized, secure gateway for all external communications. By utilizing a chain of Dio interceptors, the app achieves seamless token management, robust error reporting via Sentry, and detailed debugging through Talker. This architecture allows developers to focus on feature implementation while the network layer handles authentication persistence and file upload stability.