tryx 1.0.0 copy "tryx: ^1.0.0" to clipboard
tryx: ^1.0.0 copied to clipboard

A powerful Dart library for functional, reliable, and expressive error handling using Result types. Provides type-safe error handling without exceptions, with support for async operations, streams, an [...]

example/tryx_example.dart

// ignore_for_file: avoid_print

import 'dart:async';
import 'dart:math';

import 'package:tryx/tryx.dart';

/// Comprehensive example demonstrating Tryx error handling library features.
void main() async {
  print('šŸš€ Tryx Error Handling Library Examples\n');

  // Basic usage examples
  await basicUsageExamples();

  // Async operations
  await asyncOperationExamples();

  // Stream processing
  await streamProcessingExamples();

  // Advanced patterns
  await advancedPatternExamples();

  // Configuration examples
  configurationExamples();

  print('\nāœ… All examples completed successfully!');
}

/// Demonstrates basic Result usage and safe function execution.
Future<void> basicUsageExamples() async {
  print('šŸ“š Basic Usage Examples');
  print('=' * 50);

  // Safe function execution
  print('\n1. Safe Function Execution:');
  final parseResult = safe(() => int.parse('42'));
  parseResult.when(
    success: (value) => print('   āœ… Parsed successfully: $value'),
    failure: (error) => print('   āŒ Parse failed: $error'),
  );

  // Handling failures
  final failResult = safe(() => int.parse('invalid'));
  failResult.when(
    success: (value) => print('   āœ… Parsed: $value'),
    failure: (error) => print('   āŒ Expected failure: ${error.runtimeType}'),
  );

  // Chaining operations
  print('\n2. Chaining Operations:');
  final chainResult = safe(() => '123')
      .flatMap((str) => safe(() => int.parse(str)))
      .map((number) => number * 2)
      .map((doubled) => 'Result: $doubled');

  print('   Chain result: ${chainResult.getOrNull()}');

  // Using getOrElse for defaults
  print('\n3. Default Values:');
  final defaultResult = safe(() => int.parse('invalid')).getOrElse(() => 0);
  print('   With default: $defaultResult');

  // Recovery patterns
  print('\n4. Recovery Patterns:');
  final recoveredResult = safe(() => int.parse('invalid'))
      .recover((error) => -1)
      .map((value) => 'Recovered value: $value');
  print('   ${recoveredResult.getOrNull()}');
}

/// Demonstrates async operations with Result types.
Future<void> asyncOperationExamples() async {
  print('\n\nšŸ”„ Async Operation Examples');
  print('=' * 50);

  // Basic async safe execution
  print('\n1. Async Safe Execution:');
  final asyncResult = await safeAsync(() => simulateAsyncOperation(true));
  asyncResult.when(
    success: (value) => print('   āœ… Async success: $value'),
    failure: (error) => print('   āŒ Async failure: $error'),
  );

  // Async chaining
  print('\n2. Async Chaining:');
  final chainAsyncResult = await safeAsync(() => simulateAsyncOperation(true));

  final processedResult = await chainAsyncResult.when(
    success: (value) async => safeAsync(() => processValue(value)),
    failure: (error) async => Result<String, Exception>.failure(error),
  );

  final finalResult = processedResult.when(
    success: (processed) => 'Final: $processed',
    failure: (error) => 'Error: $error',
  );
  print('   $finalResult');

  // Error handling in async chains
  print('\n3. Async Error Handling:');
  final errorChain = await safeAsync(() => simulateAsyncOperation(false))
      .then((result) => result.recover((error) => 'Fallback value'));
  print('   Recovered: ${errorChain.getOrNull()}');
}

/// Demonstrates stream processing with Result types.
Future<void> streamProcessingExamples() async {
  print('\n\n🌊 Stream Processing Examples');
  print('=' * 50);

  // Safe stream mapping
  print('\n1. Safe Stream Mapping:');
  final numberStrings = Stream.fromIterable(['1', '2', 'invalid', '4', '5']);

  await numberStrings
      .safeMap<int, String>(
    int.parse,
    errorMapper: (error) => 'Parse error: ${error.toString()}',
  )
      .listen((result) {
    result.when(
      success: (number) => print('   āœ… Parsed: $number'),
      failure: (error) => print('   āŒ $error'),
    );
  }).asFuture();

  // Stream filtering and processing
  print('\n2. Stream Success Filtering:');
  final processedStream = Stream.fromIterable(['10', '20', 'bad', '30'])
      .safeMap<int, String>(int.parse)
      .where((result) => result.isSuccess)
      .successes()
      .map((number) => number * 2);

  await processedStream.forEach((doubled) => print('   Doubled: $doubled'));

  // Stream error recovery
  print('\n3. Stream Error Recovery:');
  await Stream.fromIterable(['1', 'invalid', '3'])
      .safeMap<int, String>(int.parse)
      .recover((error) => 0)
      .successes()
      .forEach((number) => print('   Recovered: $number'));
}

/// Demonstrates advanced error handling patterns.
Future<void> advancedPatternExamples() async {
  print('\n\nšŸ›”ļø Advanced Pattern Examples');
  print('=' * 50);

  // Circuit breaker pattern
  print('\n1. Circuit Breaker Pattern:');
  final circuitBreaker = CircuitBreaker(
    config: const CircuitBreakerConfig(
      failureThreshold: 2,
      timeout: Duration(seconds: 1),
    ),
  );

  // Simulate some failures to trip the circuit breaker
  for (var i = 0; i < 4; i++) {
    final result =
        await circuitBreaker.executeSafe(() => simulateUnreliableService(i));
    result.when(
      success: (value) => print('   āœ… Service call $i: $value'),
      failure: (error) =>
          print('   āŒ Service call $i failed: ${error.runtimeType}'),
    );
  }

  // Fallback chain
  print('\n2. Fallback Chain:');
  final fallbackChain = FallbackChain<String, Exception>()
    ..addFallback(() async => simulateFailingService('primary'))
    ..addFallback(() async => simulateFailingService('secondary'))
    ..addValueFallback('default-value');

  final fallbackResult =
      await fallbackChain.execute(() => simulateFailingService('main'));
  fallbackResult.when(
    success: (value) => print('   āœ… Fallback result: $value'),
    failure: (error) => print('   āŒ All fallbacks failed: $error'),
  );

  // Custom error types
  print('\n3. Custom Error Types:');
  final customResult = await safeWith<String, CustomError>(
    simulateCustomErrorOperation,
    errorMapper: (error) => CustomError('Mapped: ${error.toString()}'),
  );

  customResult.when(
    success: (value) => print('   āœ… Custom success: $value'),
    failure: (error) => print('   āŒ Custom error: ${error.message}'),
  );
}

/// Demonstrates configuration options.
void configurationExamples() {
  print('\n\nāš™ļø Configuration Examples');
  print('=' * 50);

  // Global configuration
  print('\n1. Global Configuration:');
  TryxConfig.configure(
    enableGlobalLogging: true,
    logLevel: LogLevel.info,
    enablePerformanceMonitoring: true,
    slowOperationThreshold: const Duration(milliseconds: 100),
  );
  print('   āœ… Global configuration applied');

  // Using presets
  print('\n2. Configuration Presets:');
  TryxConfigPresets.development();
  print('   āœ… Development preset applied');

  // Custom logging
  print('\n3. Custom Logging:');
  TryxConfig.log('This is a test log message', LogLevel.info);
  print('   āœ… Custom log message sent');

  // Reset configuration
  TryxConfig.reset();
  print('   āœ… Configuration reset to defaults');
}

// Helper functions for examples

/// Simulates an async operation that can succeed or fail.
Future<String> simulateAsyncOperation(bool shouldSucceed) async {
  await Future.delayed(const Duration(milliseconds: 50));
  if (shouldSucceed) {
    return 'Async operation completed';
  } else {
    throw Exception('Async operation failed');
  }
}

/// Processes a value asynchronously.
Future<String> processValue(String value) async {
  await Future.delayed(const Duration(milliseconds: 30));
  return 'Processed: $value';
}

/// Simulates an unreliable service for circuit breaker demo.
Future<String> simulateUnreliableService(int attempt) async {
  await Future.delayed(const Duration(milliseconds: 20));
  if (attempt < 2) {
    throw Exception('Service unavailable');
  }
  return 'Service response $attempt';
}

/// Simulates a failing service for fallback demo.
Future<Result<String, Exception>> simulateFailingService(
  String serviceName,
) async {
  await Future.delayed(const Duration(milliseconds: 10));
  if (serviceName == 'default') {
    return Result.success('$serviceName-response');
  }
  return Result.failure(Exception('$serviceName service failed'));
}

/// Simulates an operation that throws custom errors.
String simulateCustomErrorOperation() {
  final random = Random();
  if (random.nextBool()) {
    return 'Custom operation success';
  } else {
    throw StateError('Custom operation failed');
  }
}

/// Custom error class for demonstration.
class CustomError {
  const CustomError(this.message);
  final String message;

  @override
  String toString() => 'CustomError: $message';
}
1
likes
140
points
23
downloads

Publisher

unverified uploader

Weekly Downloads

A powerful Dart library for functional, reliable, and expressive error handling using Result types. Provides type-safe error handling without exceptions, with support for async operations, streams, and advanced recovery patterns.

Repository (GitHub)
View/report issues

Topics

#error-handling #functional-programming #result-type #dart #async

Documentation

API reference

License

MIT (license)

Dependencies

meta

More

Packages that depend on tryx