devinus/poison

Errors encoding protocol buffers

gogogarrett opened this issue · 3 comments

I'm having difficulties trying to encode protocol buffer messages.

Given the follow protobuf definition

enum AllowedProducts {
  maths = 1;
  reading = 2; 
}
enum AllowedPrecincts {
  my_lessons = 1;
  driving_tests = 2;
}
message X_CompleteActivity {
  required AllowedProducts product = 1; 
  required AllowedPrecincts precinct = 2;
  required AllowedEventTypes event_type = 3 [default = CompleteActivity];
  required int32 canonical_student_id = 4;
  optional int32 lesson = 5;
  optional int32 activity = 6;
  optional string created_at = 7;
}

We can see that encoding some things works, while others do not.

# all ok
iex(17)> ExProtobufs.encode(:complete_activity, [lesson: 1, activity: 1, canonical_student_id: 1, product: :rejr, precinct: :peek_a_boo])
{:ok, <<8, 5, 16, 6, 24, 2, 32, 1, 40, 1, 48, 1>>}

iex(18)> Poison.encode(<<8, 5, 16, 6, 24, 2, 32, 1, 40, 1, 48, 1>>)
{:ok, "\"\\b\\u0005\\u0010\\u0006\\u0018\\u0002 \\u0001(\\u00010\\u0001\""}

# things break
iex(19)> ExProtobufs.encode(:complete_activity, [lesson: 130, activity: 1, canonical_student_id: 1, product: :rejr, precinct: :peek_a_boo])
{:ok, <<8, 5, 16, 6, 24, 2, 32, 1, 40, 130, 1, 48, 1>>}
iex(20)> Poison.encode(<<8, 5, 16, 6, 24, 2, 32, 1, 40, 130, 1, 48, 1>>)
** (FunctionClauseError) no function clause matching in Poison.Encoder.BitString.chunk_size/3
    (poison) lib/poison/encoder.ex:127: Poison.Encoder.BitString.chunk_size(<<130, 1, 48, 1>>, nil, 1)
    (poison) lib/poison/encoder.ex:122: Poison.Encoder.BitString.escape/2
    (poison) lib/poison/encoder.ex:97: Poison.Encoder.BitString.escape/2
    (poison) lib/poison/encoder.ex:124: Poison.Encoder.BitString.escape/2
    (poison) lib/poison/encoder.ex:97: Poison.Encoder.BitString.escape/2
    (poison) lib/poison/encoder.ex:91: Poison.Encoder.BitString.escape/2
    (poison) lib/poison/encoder.ex:84: Poison.Encoder.BitString.encode/2
    (poison) lib/poison.ex:41: Poison.encode!/2
    (poison) lib/poison.ex:15: Poison.encode/2

Do you have any additional information as to why this might be? If I'm trying to do something that isn't intended?

JSON does not support encoding binary data, it can encode UTF8 strings so you can Base64 encode your binary data before calling Poison.encode or you can use a binary encoding format instead of JSON.

Correct. Also, Poison 4.0 will throw a standardized EncodeError and explain why when this happens in the future.

Great, thanks for the information!