guard<T> method
- required Future<
T> action(), - ConnectionQuality minQuality = ConnectionQuality.good,
Protects a network-sensitive action by validating the connection first.
This is the recommended way to execute critical API calls. It performs multiple checks in sequence:
- Circuit Breaker: Blocks immediately if the connection is known to be failing.
- Connectivity: Ensures the device is actually online.
- Security: Validates SecurityConfig (e.g., checks for VPN or DNS Hijacking).
- Quality: Ensures the connection meets the
minQualityrequirement.
Parameters:
action: The asynchronous operation to execute if the network is healthy.minQuality: The minimum acceptable ConnectionQuality. Defaults to ConnectionQuality.good.
Throws:
- CircuitBreakerOpenException: If the circuit is open due to recent failures.
- SecurityException: If a VPN is detected (if blocked) or DNS spoofing is found.
- PoorConnectionException: If the quality is below the requested threshold.
Returns the result of the action.
Implementation
Future<T> guard<T>({
required Future<T> Function() action,
ConnectionQuality minQuality = ConnectionQuality.good,
}) async {
// 1. Handle Circuit Breaker State
if (_circuitState == CircuitBreakerState.open) {
if (_circuitBreakerResetTime != null &&
DateTime.now().isBefore(_circuitBreakerResetTime!)) {
final remaining = _circuitBreakerResetTime!.difference(DateTime.now());
throw CircuitBreakerOpenException(
'Circuit breaker is open due to recent failures. Retry after ${remaining.inSeconds}s',
retryAfter: remaining);
} else {
// Transition to Half-Open to allow a probe
_circuitState = CircuitBreakerState.halfOpen;
}
}
// 2. Perform or reuse network check
final report = await check();
// 3. Validate security requirements
if (_config.security.blockVpn && report.securityFlagsResult.isVpnDetected) {
throw SecurityException(
SecurityAlert.vpnDetected, 'VPN connection is not allowed.');
}
if (_config.security.detectDnsHijack &&
report.securityFlagsResult.isDnsSpoofed) {
throw SecurityException(SecurityAlert.dnsHijackDetected,
'DNS hijacking was detected. Connection is insecure.');
}
// 4. Validate quality requirements
if (!report.status.isConnected ||
report.status.quality.index > minQuality.index) {
throw PoorConnectionException(
'Connection quality (${report.status.quality.name}) is below required (${minQuality.name}).');
}
// 5. Success: Close circuit if it was half-open
if (_circuitState == CircuitBreakerState.halfOpen) {
_circuitState = CircuitBreakerState.closed;
_consecutiveFailures = 0;
}
return await action();
}