json_annotation_tools 0.0.2
json_annotation_tools: ^0.0.2 copied to clipboard
Transform cryptic JSON parsing errors into crystal-clear, actionable error messages. Debug JSON issues in seconds, not hours. Perfect companion to json_annotation and json_serializable.
JSON Annotation Tools ๐ ๏ธ #
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_annotationandjson_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:
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 #
- Keep Both Methods: Maintain both
fromJsonandfromJsonSafefor backward compatibility - Use in Development: Use
fromJsonSafeduring development and testing - Production Strategy: Consider using
fromJsonSafein production for critical models - Error Handling: Always wrap safe parsing in try-catch blocks
- 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 #
- Keep existing code working: Your current
fromJsonmethods continue to work - Add safe alternatives: Create
fromJsonSafemethods alongside existing ones - Test thoroughly: Use
fromJsonSafein tests to catch issues early - 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?
- Create an issue: https://github.com/khokanuzzaman/json_annotation_tools/issues
- Include details: Error messages, code examples, expected vs actual behavior
๐ก Contribute Code: #
- Fork the repository: https://github.com/khokanuzzaman/json_annotation_tools
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - 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_annotationandjson_serializablepackages - 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!