-
Notifications
You must be signed in to change notification settings - Fork 863
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
Fix DynamoDbv2 bug for incorrect DateTime epoch serialization when date falls out of epoch supported range #3672
base: main-staging
Are you sure you want to change the base?
Conversation
f64cf2c
to
b7fb176
Compare
|
||
if (dateTime.HasValue) | ||
{ | ||
entry = (Primitive)(dateTime.Value); |
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.
if we want to modify the caller's reference of entry shouldn't we do something like:
entry = new Primitive(datetime.Value)
Aren't we just modifying the local copy of the reference here? I see that being done below, but maybe you forgot that here?
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.
This was copied from the existing EpochSecondsToDateTime.
Yes, we are just modifying the local copy of the reference here and then returning it. entry = new Primitive(datetime.Value)
would also the same, but in a more elegant way. 😄
The function DateTimeToEpochSecondsLong()
was added by customer which uses new Primitive(epochSecondsAsString, saveAsNumeric: true)
, so didn't touched it.
@@ -822,7 +835,7 @@ private static void PopulateConfigFromType(ItemStorageConfig config, Type type) | |||
} | |||
} | |||
} | |||
|
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.
nit: added whitespace?
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.
Removed it somehow.
|
||
// To prevent the data from being (de)serialized incorrectly, we choose to throw the exception instead | ||
// of swallowing it. | ||
throw; |
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.
We should throw our own exception calling out our failure to convert the DateTime
to a Epoch. Provide the value of the DateTime, attributeName
, and the original exception as the inner exception. If we don't users will get a random numeric conversion exception and have no context why they are getting the error and how to fix it.
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.
Done. Please review.
"Encountered error attempting to convert '{0}' with value '{1}' to epoch seconds: {1}", | ||
attributeName, entry, e); | ||
|
||
// To prevent the data from being (de)serialized incorrectly, we choose to throw the exception instead |
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.
For historical purposes can you call out in the comment this was a purposeful change from the existing DateTimeToEpochSeconds
to avoid issues silently fallback to string format DateTime.
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.
Done
throw; | ||
} | ||
|
||
if (epochSecondsAsString != null) |
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.
This can never be false anymore since we are always throwing an exception if we fail to convert. To avoid the code getting refactored in weird ways in the future I would add line 336 right after the ConvertToUnixEpochSecondsString
call and then return. That would leave no code after the catch block and we don't need the extra if check.
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.
Done. Please review.
@@ -346,6 +354,7 @@ public void TestContext_CustomDateTimeConverter(bool retrieveDateTimeInUtc) | |||
Context.ConverterCache.Add(typeof(DateTime), new DateTimeUtcConverter()); | |||
|
|||
var currTime = DateTime.Now; | |||
var longEpochTime = new DateTime(2039, 2, 5, 17, 49, 55, DateTimeKind.Local); // DateTime.Now returns Local kind. |
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.
Can you add a test that uses a date before 1970 the start of the Unix epoch?
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.
Used var currTimeBefore1970 = new DateTime(1969, 6, 12, 4, 56, 43, DateTimeKind.Local);
for attribute EpochDate2
(it was somehow not decorated with StoreAsEpoch
. Decorated it with StoreAsEpoc
.
Please advise if we need to also test it with StoreAsEpochLong
.
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.
Fixed
@@ -0,0 +1,11 @@ | |||
{ | |||
"services": [ | |||
{ |
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.
You also changed Core
(sdk/src/Core/Amazon.Util/AWSSDKUtils.cs
) but didn't include it here.
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.
Thanks for catching it. Fixed.
9ea348c
to
5eba8fd
Compare
5eba8fd
to
037f1b2
Compare
values outside of 2038 will silently be converted to its original value, in this case, a datetime.
This prevents big API changes
…rrect DateTime epoch serialization issue.
037f1b2
to
7bce707
Compare
Description
Taking over the PR #3442 to get it across finish line. @sander1095 Thanks for the initial PR.
NOTE (for reviewer):
AWSSSDKUtils.ConvertFromUnixEpochSeconds(long)
to convert the stored epoch seconds string back toDateTime
. Please review for it's correctness.IMPORTANT: Per @boblodgett, there were some UTC DateTime fix implemented in V4. So we need to make sure we don't overwrite these when merging to
v4-development
branch.Motivation and Context
#3442
Testing
Dry run
DRY_RUN-3c72ed89-be29-4254-9bd1-299cbc34e081
completed successfully.Screenshots (if appropriate)
Types of changes
Checklist
License