Json module: error when encoding text with accents

Hi guys

I’ve got a list of binaries to encode in JSON.

As you can see, the second binary in the list is in french:

Erlang/OTP 27 [erts-15.1] [source] [64-bit] [smp:8:8] [ds:8:8:8] [async-threads:1]

1> L = [ <<"100872">>, <<"STABILO: spécialement conçu pour l'écriture...">>, <<"HB">> ].
2> json:encode(L).
** exception error: {invalid_byte,99}
     in function  json:invalid_byte/2 (json.erl, line 539)
     in call from json:list_loop/2 (json.erl, line 244)
     in call from json:do_encode_list/2 (json.erl, line 241)

Is there a way to encode this text before calling json:encode/1?

Thanks

Is this the way to go?

Erlang/OTP 27 [erts-15.1] [source] [64-bit] [smp:8:8] [ds:8:8:8] [async-threads:1]
1> L = [ <<"100872">>, <<"STABILO: spécialement conçu pour l'écriture...">>, <<"HB">> ].
2> json:encode([unicode:characters_to_binary(Bin,latin1) || Bin <- L]).
[91,
 [34,<<"100872">>,34],
 44,
 [34,
  <<"STABILO: spécialement conçu pour l'écriture..."/utf8>>,
  34],
 44,
 [34,<<"HB">>,34],
 93]

You have missed the /utf8 in <<“STABILO: spécialement conçu pour l’écriture…”>>:

Erlang/OTP 27 [erts-15.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]

Eshell V15.1 (press Ctrl+G to abort, type help(). for help)
1> L = [ <<"100872">>, <<"STABILO: spécialement conçu pour l'écriture..."/utf8>>, <<"HB">> ].
[<<"100872">>,
 <<"STABILO: spécialement conçu pour l'écriture..."/utf8>>,
 <<"HB">>]
2> json:encode(L).
[91,
 [34,<<"100872">>,34],
 44,
 [34,
  <<"STABILO: spécialement conçu pour l'écriture..."/utf8>>,
  34],
 44,
 [34,<<"HB">>,34],
 93]

Or use the new syntax with sigils:

3> L = [ ~"100872", ~"STABILO: spécialement conçu pour l'écriture...", ~"HB" ].
[<<"100872">>,
 <<"STABILO: spécialement conçu pour l'écriture..."/utf8>>,
 <<"HB">>]
1 Like

Hi @williamthome

I don’t control these binaries. I got them from a socket.
Do you think my solution is OK?

One alternative is to use json:encode/2, overriding the encoder, like:

1> L = [ <<"100872">>, <<"STABILO: spécialement conçu pour l'écriture...">>, <<"HB">> ].
[<<"100872">>,
 <<"STABILO: spécialement conçu pour l'écriture...">>,
 <<"HB">>]
2> Encoder = fun(Value, E) -> case is_binary(Value) of true -> unicode:characters_to_binary(Value, latin1); false -> json:encode_value(Value, E) end end.
#Fun<erl_eval.41.39164016>
3> json:encode(L, Encoder).
[91,<<"100872">>,44,
 <<"STABILO: spécialement conçu pour l'écriture..."/utf8>>,
 44,<<"HB">>,93]
1 Like

@williamthome Thanks a lot.

1 Like