The default Encoder[Instant] instance fails for dates very far in the future
Closed this issue · 1 comments
Description
The default Encoder[Instant]
instance fails with a java.lang.ArithmeticException: long overflow
error when trying to encode dates that are very far in the future.
The cause of the bug is that the default Encoder
represents time values as Long
millisecond timestamps, although Instant
is capable of storing much larger values than what a Long
can.
Example
import meteor.syntax._
import java.time.Instant
val t = Instant.ofEpochMilli(Long.MaxValue).plusMillis(1)
t.asAttributeValue // throws ArithmeticException
Possible solution
Changing Encoder[Instant]
to represent values as ISO strings.
This would also have the added benefit of not truncating sub-millisecond values.
implicit val InstantCodec: Codec[Instant] =
new Codec[Instant] {
def read(av: AttributeValue): Either[DecoderError, Instant] =
av.as[String].flatMap { str =>
Either
.catchNonFatal(Instant.parse(str))
.left
.map(err => DecoderError(err.getMessage(), err.getCause().some))
}
def write(a: Instant): AttributeValue = a.toString().asAttributeValue
}
good point. However, this only happens for very very large value. By changing the default Codec
, it potentially will break all existing data which has been written as Long
. Personally I think if you are effected by this bug, you can provide your custom Codec instead of using the one provided by the lib. A proper fix would be provide a Codec that is compatible with both formats.