-
Notifications
You must be signed in to change notification settings - Fork 46
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
Improve error message for validation errors in System.Test.Json deserialization #735
Conversation
Thank you very much @Peter-B- ! The I think the approach you've taken with a separate method is the correct one as it removes the STJ dependency for every value object. I think we should explore ways of hooking into the Thanks again for this, much appreciated - I do think it will make diagnosing serialization issues much easier. |
Hi @SteveDunn, I've seen the If I understand it correctly, this means we have to generate the complete deserialization, normalization and validation into a placeholder in the template. It might look like this: private static MyVoString DeserializeJson(System.String value)
{
if (value is null)
{
ThrowHelper.ThrowJsonExceptionWhenCreatedWithNull();
return default !;
}
value = MyVoString.NormalizeInput(value);
var validation = MyVoString.Validate(value);
if (validation != Vogen.Validation.Ok)
{
ThrowHelper.ThrowJsonExceptionWhenValidationFails(validation);
}
return new MyVoString(value);
} What do you think? Actually, I'm not sure how I would implement this (reuse and modify the existing code to throw another exception with an inner exception), so if you like to do that, I'd be glad to hand over :-) Reusing the |
Hello @SteveDunn, I have extended my implementation and the result looks something like #if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
#endif
private static void ThrowJsonExceptionWhenValidationFails(Vogen.Validation validation)
{
var e = ThrowHelper.CreateValidationException(validation);
throw new global::System.Text.Json.JsonException(null, e);
}
private static void ThrowJsonExceptionWhenNull(System.String value)
{
if (value == null)
{
var e = ThrowHelper.CreateCannotBeNullException();
throw new global::System.Text.Json.JsonException(null, e);
}
}
public static MyVoString_should_not_bypass_validation DeserializeJson(System.String value)
{
ThrowJsonExceptionWhenNull(value);
value = MyVoString_should_not_bypass_validation.NormalizeInput(value);
var validation = MyVoString_should_not_bypass_validation.validate(value);
if (validation != Vogen.Validation.Ok)
{
ThrowJsonExceptionWhenValidationFails(validation);
}
return new MyVoString_should_not_bypass_validation(value);
} The I put the throw helper methods directly into each converter, which is some duplication again, but I didn't know where to put them and how to track, if another converter already created the necessary classes. I didn't do thorough testing yet. Can you please take a look at it and tell me if this goes into the right direction? Thank you |
Looking great, many thanks @Peter-B- ! I forgot just how confusing that STJ code can be, what with templates and replaceable code etc! One thing that might be worth considering is if users have configured Vogen to throw a different validation exception. But then again, I guess it would be unusual to deserialise something and rely solely on that exception type to signify errors. I'm rebasing the snapshot tests now (running by running Thanks again! |
Oh no I didn't, it just took a while to come through |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks very much Peter!
Great! I have to admit that I was confused at times, but the naming and code style is good and so I found my way around. It is indeed hard to say, if this is a breaking change - of course there is no such thing as a non-breaking change. I think it is definitely an improvement, but you might also want to wait for a major release. |
Thank you - yes, I intend to release this as the first beta of 7.0.0 to see if anyone complains. Hopefully it won't impact anyone, and the plus side will be far more detailed exceptions when deserialising. Thanks for all your efforts with this one! |
This PR addresses #723 by throwing
JsonException
s, when the creation or validation of a Vogen object fails duringSystem.Text.Json
deserialization.All JsonConverter templates were updated to include a method
This method is invoked from both
Read
andReadAsPropertyName
.The converters for both
DateOnly
andTimeOnly
directly invoked the constructor before. Please review those changes carefully, since I have the feeling, I broke something there.I added some unit tests for Json deserialization, adapted existing ones, and updated the snapshots. Please let me know, if I missed something or should adapt the code.
Kind regards
Peter
PS: I grossly underestimated the effort you put into this project. Thanks a lot for sharing this with the community!