flutter_resilience 1.0.2 copy "flutter_resilience: ^1.0.2" to clipboard
flutter_resilience: ^1.0.2 copied to clipboard

A production-ready Flutter/Dart package for network resilience.

example/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_resilience/flutter_resilience.dart';
import 'dart:async';

void main() {
  runApp(const ResilienceExampleApp());
}

class ResilienceExampleApp extends StatelessWidget {
  const ResilienceExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Resilience Demo',
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        brightness: Brightness.dark,
      ),
      home: const ResilienceHomePage(),
    );
  }
}

class ResilienceHomePage extends StatefulWidget {
  const ResilienceHomePage({super.key});

  @override
  State<ResilienceHomePage> createState() => _ResilienceHomePageState();
}

class _ResilienceHomePageState extends State<ResilienceHomePage> {
  final List<String> _logs = [];
  bool _isLoading = false;
  late ResilientClient _client;
  late CircuitBreaker _circuitBreaker;

  @override
  void initState() {
    super.initState();
    _circuitBreaker = CircuitBreaker(
      failureThreshold: 3,
      resetTimeout: const Duration(seconds: 5),
      onStateChanged: (state) =>
          _addLog('Circuit State: ${state.name.toUpperCase()}'),
    );

    _client = ResilientClient(
      retries: 3,
      strategy: RetryStrategy.exponential,
      retryDelay: const Duration(seconds: 1),
      circuitBreaker: _circuitBreaker,
      timeout: const Duration(seconds: 2),
      retryIf: (error) => error is Exception,
    );
  }

  void _addLog(String message) {
    setState(() {
      _logs.insert(0,
          '${DateTime.now().toIso8601String().split('T').last.substring(0, 8)}: $message');
    });
  }

  Future<void> _simulateRequest(bool shouldFail) async {
    setState(() => _isLoading = true);
    _addLog('Executing Request (Should Fail: $shouldFail)...');

    try {
      final result = await _client.execute(
        () async {
          _addLog('Attempting request...');
          await Future<void>.delayed(const Duration(milliseconds: 500));
          if (shouldFail) {
            throw Exception('Simulated API Failure');
          }
          return 'Success Data from API';
        },
        fallback: () => 'Fallback Data (Offline Cache)',
      );
      _addLog('RESULT: $result');
    } catch (e) {
      _addLog('ERROR: $e');
    } finally {
      setState(() => _isLoading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Resilience Demo'),
        actions: [
          IconButton(
            onPressed: () {
              setState(_logs.clear);
              _circuitBreaker.reset();
            },
            icon: const Icon(Icons.refresh),
          ),
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const _InfoCard(),
            const SizedBox(height: 16),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed:
                        _isLoading ? null : () => _simulateRequest(false),
                    icon: const Icon(Icons.check_circle),
                    label: const Text('Success Request'),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.green.withAlpha(51),
                    ),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton.icon(
                    onPressed: _isLoading ? null : () => _simulateRequest(true),
                    icon: const Icon(Icons.error),
                    label: const Text('Failing Request'),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.red.withAlpha(51),
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 16),
            const Text('Logs',
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
            const SizedBox(height: 8),
            Expanded(
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.black26,
                  borderRadius: BorderRadius.circular(8),
                  border: Border.all(color: Colors.white10),
                ),
                child: ListView.separated(
                  padding: const EdgeInsets.all(8),
                  itemCount: _logs.length,
                  separatorBuilder: (_, __) =>
                      const Divider(height: 1, color: Colors.white10),
                  itemBuilder: (context, index) {
                    final log = _logs[index];
                    return Padding(
                      padding: const EdgeInsets.symmetric(vertical: 4),
                      child: Text(
                        log,
                        style: TextStyle(
                          fontFamily: 'Courier',
                          color: log.contains('ERROR')
                              ? Colors.redAccent
                              : (log.contains('Success')
                                  ? Colors.greenAccent
                                  : Colors.white70),
                        ),
                      ),
                    );
                  },
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _InfoCard extends StatelessWidget {
  const _InfoCard();

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              'Configuration:',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 4),
            const Text('• Retries: 3 with Exponential Backoff'),
            const Text('• Timeout: 2 seconds'),
            const Text('• Circuit Breaker Threshold: 3 failures'),
            const Text('• Reset Timeout: 5 seconds'),
            const SizedBox(height: 8),
            Text(
              'Watch the logs to see retry attempts and circuit state transitions.',
              style: TextStyle(
                  color: Theme.of(context).colorScheme.primary,
                  fontStyle: FontStyle.italic),
            ),
          ],
        ),
      ),
    );
  }
}
1
likes
160
points
181
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A production-ready Flutter/Dart package for network resilience.

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

async, flutter, http

More

Packages that depend on flutter_resilience