json_annotation_tools 0.0.3 copy "json_annotation_tools: ^0.0.3" to clipboard
json_annotation_tools: ^0.0.3 copied to clipboard

Transform cryptic JSON parsing errors into crystal-clear, actionable error messages. Perfect companion to json_annotation.

JSON Annotation Tools ๐Ÿ› ๏ธ #

pub package License: MIT

Stop wrestling with cryptic JSON parsing errors! This package provides powerful debugging tools and safe parsing utilities that make JSON deserialization errors crystal clear and easy to fix.

[Error Comparison Demo] Before vs After: See how error messages transform from cryptic to crystal clear

๐ŸŽฏ Why You Need This #

Ever seen this frustrating error?

type 'String' is not a subtype of type 'int'

And spent hours figuring out which field in your JSON caused it? Those days are over.

Before vs After #

โŒ Before (Standard JSON parsing):

// Unclear error: "type 'String' is not a subtype of type 'int'"
// Which field? What value? Who knows! ๐Ÿคทโ€โ™‚๏ธ
User.fromJson(json);

โœ… After (With JSON Annotation Tools):

// Crystal clear error message:
// "โŒ Error parsing key 'age': expected int, but got String. Value: "25""
User.fromJsonSafe(json);

[Complete Demo Flow] ๐ŸŽฌ See the complete debugging experience in action

๐Ÿš€ Features #

  • ๐Ÿ” Pinpoint Error Location: Know exactly which JSON field caused the parsing error
  • ๐Ÿ“ Detailed Error Messages: See the expected type, actual type, and problematic value
  • ๐Ÿ›ก๏ธ Type Safety: Catch type mismatches before they crash your app
  • ๐Ÿšซ Missing Field Detection: Clear warnings for missing required fields
  • ๐Ÿ”„ Seamless Integration: Works perfectly with json_annotation and json_serializable
  • โšก Zero Performance Impact: Only active during parsing errors
  • ๐ŸŒ Cross-Platform: Works on iOS, Android, Web, macOS, Windows, Linux

๐Ÿ“ฑ Interactive Demo App #

Experience the power of enhanced error messages with our interactive demo app:

[Demo App Home]

Try all features live on Android, iOS, or Web!

What You'll See: #

  • ๐Ÿšจ Real Error Comparisons: Before vs after side-by-side
  • ๐Ÿ”ง Copy-Paste Solutions: Ready-to-use code fixes
  • ๐ŸŽฏ Smart Suggestions: AI-powered field name matching
  • ๐Ÿ” Advanced Diagnostics: Property mapping analysis
  • โšก Live Testing: Try different JSON scenarios instantly

๐Ÿ“ฆ Installation #

Add to your pubspec.yaml:

dependencies:
  json_annotation_tools: ^0.0.1
  json_annotation: ^4.9.0

๐ŸŽฎ Quick Start #

1. Import the package #

import 'package:json_annotation_tools/json_annotation_tools.dart';

2. Use in your JSON models #

Traditional approach (error-prone):

@JsonSerializable()
class User {
  final int id;
  final String name;
  final int age;
  
  User({required this.id, required this.name, required this.age});
  
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}

Enhanced approach (bulletproof):

@JsonSerializable()
class User {
  final int id;
  final String name;
  final int age;
  
  User({required this.id, required this.name, required this.age});
  
  // Original method (keep for compatibility)
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  
  // Enhanced method with detailed error reporting
  factory User.fromJsonSafe(Map<String, dynamic> json) {
    return User(
      id: json.getSafe('id', (v) => v as int),
      name: json.getSafe('name', (v) => v as String),
      age: json.getSafe('age', (v) => v as int),
    );
  }
}

3. Handle problematic JSON gracefully #

final problematicJson = {
  'id': 123,
  'name': 'John Doe',
  'age': '25', // Oops! String instead of int
};

try {
  final user = User.fromJsonSafe(problematicJson);
} catch (e) {
  print(e);
  // Output: โŒ Error parsing key 'age': expected int, but got String. Value: "25"
  // Now you know exactly what to fix!
}

๐ŸŽฏ Real-World Examples #

API Response Debugging #

// When your API suddenly returns unexpected data types
final apiResponse = {
  'user_id': '12345',    // Should be int, but API returned string
  'balance': 'null',     // Should be double, but got string "null"
  'premium': 1,          // Should be bool, but got int
};

// Get clear, actionable error messages:
try {
  final user = User.fromJsonSafe(apiResponse);
} catch (e) {
  // โŒ Error parsing key 'user_id': expected int, but got String. Value: "12345"
  // Now you can immediately contact the backend team with specific details!
}

Nullable Fields Made Easy #

factory User.fromJsonSafe(Map<String, dynamic> json) {
  return User(
    id: json.getSafe('id', (v) => v as int),
    name: json.getSafe('name', (v) => v as String),
    age: json.getSafe('age', (v) => v as int),
    // Optional fields with safe parsing
    email: json.getNullableSafe('email', (v) => v as String),
    phoneNumber: json.getNullableSafe('phone', (v) => v as String),
  );
}

Complex Type Parsing #

// Parse nested objects and lists safely
factory Order.fromJsonSafe(Map<String, dynamic> json) {  
  return Order(
    id: json.getSafe('id', (v) => v as String),
    items: json.getSafe('items', (v) => 
      (v as List).map((item) => OrderItem.fromJsonSafe(item)).toList()
    ),
    totalAmount: json.getSafe('total', (v) => (v as num).toDouble()),
    createdAt: json.getSafe('created_at', (v) => DateTime.parse(v as String)),
  );
}

๐Ÿ”ง Advanced Usage #

Custom Parser Functions #

// Create reusable parsers for common patterns
T parseEnum<T>(List<T> values, dynamic value) {
  final stringValue = value as String;
  return values.firstWhere(
    (e) => e.toString().split('.').last == stringValue,
    orElse: () => throw FormatException('Invalid enum value: $stringValue'),
  );
}

// Use in your models
factory UserStatus.fromJsonSafe(Map<String, dynamic> json) {
  return UserStatus(
    status: json.getSafe('status', (v) => parseEnum(StatusType.values, v)),
  );
}

Debugging Production Issues #

// Add logging to track parsing issues in production
factory User.fromJsonSafe(Map<String, dynamic> json) {
  try {
    return User(
      id: json.getSafe('id', (v) => v as int),
      name: json.getSafe('name', (v) => v as String),
      age: json.getSafe('age', (v) => v as int),
    );
  } catch (e) {
    // Log the error with full context for debugging
    FirebaseCrashlytics.instance.recordError(
      e, 
      null, 
      fatal: false,
      information: ['JSON: ${jsonEncode(json)}'],
    );
    rethrow;
  }
}

๐ŸŽจ Best Practices #

  1. Keep Both Methods: Maintain both fromJson and fromJsonSafe for backward compatibility
  2. Use in Development: Use fromJsonSafe during development and testing
  3. Production Strategy: Consider using fromJsonSafe in production for critical models
  4. Error Handling: Always wrap safe parsing in try-catch blocks
  5. Logging: Log parsing errors with full context for debugging

๐Ÿ”— Works Great With Your Stack #

Perfect integration with Dio, Retrofit, and json_annotation - use the same safe parsing methods with your existing API client setup.

๐Ÿค Migration Guide #

From Standard JSON Serialization #

  1. Keep existing code working: Your current fromJson methods continue to work
  2. Add safe alternatives: Create fromJsonSafe methods alongside existing ones
  3. Test thoroughly: Use fromJsonSafe in tests to catch issues early
  4. Gradual adoption: Migrate critical models first, then expand usage

๐Ÿ“Š Performance Impact #

  • Zero overhead during successful parsing
  • Minimal impact during errors (only when you need the debugging info)
  • Same memory usage as standard parsing
  • Compatible with all existing JSON serialization patterns

๐ŸŒ Platform Support #

This package works seamlessly across all Flutter/Dart platforms:

โœ… Fully Supported Platforms: #

  • ๐Ÿ“ฑ iOS: Native iOS apps (iPhone/iPad)
  • ๐Ÿค– Android: Native Android apps (phones/tablets)
  • ๐ŸŒ Web: Progressive Web Apps (PWA) and web browsers
  • ๐Ÿ’ป macOS: Native desktop apps
  • ๐ŸชŸ Windows: Native desktop apps
  • ๐Ÿง Linux: Native desktop apps

๐Ÿ“ฆ Package Type: #

  • Pure Dart package - no platform-specific code
  • No native dependencies - works everywhere Flutter works
  • Same API across all platforms
  • Consistent behavior regardless of target platform

๐ŸŽฎ Try the Demo: #

Run our interactive example app to test on your preferred platform:

# iOS (requires Xcode and iOS Simulator/Device)
cd example_app && flutter run -d ios

# Android (requires Android SDK and Emulator/Device)  
cd example_app && flutter run -d android

# Web (opens in default browser)
cd example_app && flutter run -d chrome

# macOS (requires macOS development setup)
cd example_app && flutter run -d macos

# Windows (requires Windows development setup)
cd example_app && flutter run -d windows

# Linux (requires Linux development setup)
cd example_app && flutter run -d linux

๐Ÿ› Troubleshooting #

Common Issues #

Q: "I'm getting errors about missing keys"

// Use getNullableSafe for optional fields
email: json.getNullableSafe('email', (v) => v as String),

Q: "How do I handle nested objects?"

// Parse nested objects recursively
address: json.getSafe('address', (v) => Address.fromJsonSafe(v as Map<String, dynamic>)),

Q: "Can I use this with existing json_serializable models?"

// Yes! Add safe methods alongside generated ones
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); // Generated
factory User.fromJsonSafe(Map<String, dynamic> json) { /* Your safe implementation */ }

๐Ÿค Contributing #

We welcome contributions! Here's how to get involved:

๐Ÿ› Report Issues: #

Found a bug or have a feature request?

๐Ÿ’ก Contribute Code: #

  1. Fork the repository: https://github.com/khokanuzzaman/json_annotation_tools
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to branch: git push origin feature/amazing-feature
  5. Open a Pull Request

๐Ÿ“– Improve Documentation: #

  • Fix typos or unclear explanations
  • Add more examples or use cases
  • Enhance visual documentation

๐Ÿงช Add Tests: #

  • Write tests for new features
  • Improve existing test coverage
  • Add edge case testing

Please see our Contributing Guide for detailed guidelines.

๐Ÿ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgments #

  • Built to complement the excellent json_annotation and json_serializable packages
  • Inspired by the need for better JSON debugging in Flutter development
  • Thanks to the Flutter community for feedback and suggestions

Made with โค๏ธ for the Flutter community

Stop debugging JSON parsing errors in the dark - see exactly what's wrong and fix it fast!

2
likes
0
points
54
downloads

Publisher

verified publisherkhokan.me

Weekly Downloads

Transform cryptic JSON parsing errors into crystal-clear, actionable error messages. Perfect companion to json_annotation.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, json_annotation, meta

More

Packages that depend on json_annotation_tools