replicate / replicate-swift

Swift client for Replicate
https://replicate.com
Apache License 2.0
157 stars 33 forks source link

Invalid Date Format #58

Closed longseespace closed 10 months ago

longseespace commented 10 months ago

Overview

Fetching model prompthero/openjourney (https://replicate.com/prompthero/openjourney) fails with this error:

dataCorrupted(Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "default_example", intValue: nil), CodingKeys(stringValue: "started_at", intValue: nil)], debugDescription: "Invalid date: 2022-11-15T02:17:27Z", underlyingError: nil))

The culprit:

private extension JSONDecoder.DateDecodingStrategy {
    static let iso8601WithFractionalSeconds = custom { decoder in
        let formatter = ISO8601DateFormatter()
        formatter.formatOptions = [.withFullDate,
                                   .withFullTime,
                                   .withFractionalSeconds]

        let container = try decoder.singleValueContainer()
        let string = try container.decode(String.self)

        guard let date = formatter.date(from: string) else {
            throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: \(string)")
        }

        return date
    }
}
longseespace commented 10 months ago

Fixed in https://github.com/replicate/replicate-swift/pull/59

mattt commented 10 months ago

Thank you so much for reporting and contributing a fix, @longseespace.

For the life of me, I can't figure out why some dates are being serialized from the server with fractional seconds and some without. But given Swift / Foundation's inflexibility on parsing, turning off fractional seconds would break existing clients.

I found this Swift.org forum thread from 2019 reporting this issue. It's too bad that there doesn't seem to be a better way to solve this than trying again with different options.

I just merged #60, which extends #59 to use .withInternetDateTime instead of .withFullDate | .withFullTime, reuse the existing formatter instance, and exercise this with a new DateDecodingTests class.

This is now fixed in 0.17.1.