Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling DeserializationError for backwards compatibility #1342

Open
deepakg202 opened this issue Feb 3, 2025 · 3 comments
Open

Handling DeserializationError for backwards compatibility #1342

deepakg202 opened this issue Feb 3, 2025 · 3 comments
Assignees
Labels

Comments

@deepakg202
Copy link

deepakg202 commented Feb 3, 2025

Is there a way we can add some fallback value to a field (behaviour similar to enums) if the type does not exist for deserialization ? We want to add more types in new app releases but it breaks previous versions.

@davidmorgan davidmorgan self-assigned this Feb 3, 2025
@davidmorgan
Copy link
Collaborator

Yes, make the field have a default.

The simplest way to add a default for a field is usually to add a @BuiltValueHook that initializes the builder: https://pub.dev/documentation/built_value/latest/built_value/BuiltValueHook/initializeBuilder.html

@BuiltValueHook(initializeBuilder: true)
static void _initialize(MyClassBuilder b) =>
   b..name = 'defaultName';

@deepakg202
Copy link
Author

This does not work. It still throws the error. I think you misunderstood my issue.

Suppose i have a base class say InputSource with @BuiltValue(instantiable: false) and I created a subclass from it eg. GalleryInputSource and released the app. But later if I wanted to add another subclass eg. CameraInputSource, it wont be backwards compatible and fail the entire deserialization on older apps. Is there a way I can handle these cases ? I was hoping if we can add a flag to ignore DeserializationError and continue with the default value.

@davidmorgan
Copy link
Collaborator

Ah, sorry, yes, now I understand.

I don't see any good way to do that today; here are a few workarounds that come to mind:

  • you could send a list of the class names to the client, e.g. ['CameraInputSource'], and for each one it could check if a serializer is available, and if not install a Serializer<Null> that returns that string for wire name, and always deserializes to null
  • or, you could write a custom serializer for InputSource that looks up the serializer and calls it if present, returns null if not found
  • or, you could write a serializer plugin that removes unknown JSON using a local list of valid classes

in terms of supporting as a feature ... I guess Serializers could have an option that you set once at runtime to return null on unknown type instead of throwing? You would have to make sure the field or collection of InputSource is nullable. Or we could do something like that but just for collections.

It starts to get quite complicated :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants