Poison can't encode date in staging environment

I’ve just upgraded a Phoenix app to 1.3 and Elixir 1.5.2. Now I get an exception on staging but not locally. I’ve traced it down (after getting some help from @michalmuskala on Slack) to when Poison encodes dates.

I use Poison 3.1, and this is the error I get:

** (Poison.EncodeError) unable to encode value: {0, 6}

    (poison) lib/poison/encoder.ex:383: Poison.Encoder.Any.encode/2

    (poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3

    (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3

    (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3

    (poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3

    (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3

    (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3

I only return Maps from my render functions (not using @derive in model/schema).

The Map that fails to encode looks like this:

%{id: 216, images: [%{aspect_ratio: 1.33333, id: 194, urls: %{original: "https://example.com/foo.jpg?v=63674938035", small: "https://example.com/foo.jpg?v=63674938035", thumb: "https://example.com/foo.jpg?v=63674938035"}}], inserted_at: ~N[2017-10-11 10:46:53.000000], tag_list: ["foo", "bar", "baz", "qux"], text: "Some text", thread: %{address: "Address 1", area: 100, district: nil, id: 127, interest_count: 4, internal_id: "23852", location: %{lat: 57.7456204, long: 11.9868868}, lot_size: nil, price: 2500000, property_type: %{id: 3, name: "FooBar"}, realtor: %{avatar_url: "https://example.com/avatar.jpg?v=63674969635", email: "foobar@example.com", first_name: "Foo", id: 78, last_name: "Bar", realtor: true}, rooms: #Decimal<4.0>, status: 2, title: "Some title", user_interest_level: 0, web_url: "https://example.com/threads/127"}, thread_id: 127, updated_at: ~N[2017-10-11 10:46:53.000000]}

And from what I can find it’s the NaiveDateTime that breaks.

Any ideas on how to fix this?

1 Like

For now I convert the NaiveDateTime myself with NaiveDateTime.to_iso8601(post.updated_at) etc.

1 Like

I suspect it might be a precision issue. If you are using Postgres it can have different settings for precision of timestamps, i.e. how many digits are after dot separating seconds from miliseconds etc. Check out the settings in your Postgres and see documentation here: https://www.postgresql.org/docs/9.1/static/datatype-datetime.html

I supect that maybe on your staging environment, you have high precision configured for timestamps. The default can be changed in Postgres’s config file. And that somehow Poison can’t understand such high precision. It’s a guess, I’ll leave it up to you to investigate.

2 Likes

Thank you, that sounds plausible! Will check when I’m back at work.

1 Like

Don’t forget to update us here. If this is the case, it’s most likely a bug somewhere either in Elixir or Ecto or Poison that needs to be fixed. This should not happen.

1 Like

Definitely :+1:

1 Like