Jason.DecodeError on Phoenix Websocket with Cowboy2

Hi guys i have implemented websocket to my phoenix app. Before it success to connected and joined room to my websocket, but right now i got this error

[error] Ranch listener MarketPlaceDisbursementServiceWeb.Endpoint.HTTP had connection process 
started with :cowboy_clear:start_link/4 at #PID<0.499.0> exit with reason: {%Jason.DecodeError
{data: "{   \"topic\": \"room:marketplace_disbursement_service\",   \"event\": \"inquiry_response\", 
  \"payload\": {},   \"ref\": 0 }", position: 2, token: nil}, [{Jason, :decode!, 2, [file: 'lib/jason.ex', line: 78]}, {Phoenix.Socket.V1.JSONSerializer, :decode!, 2, [file: 'lib/phoenix/socket/serializers/v1_json_serializer.ex',
 line: 29]}, {Phoenix.Socket, :__in__, 2, [file: 'lib/phoenix/socket.ex', line: 498]}, '{Phoenix.Endpoint.Cowboy2Handler, :websocket_handle, 2, [file: 'lib/phoenix/endpoint/cowboy2_handler.ex', line: 77]}, {:cowboy_websocket, :handler_call, 6, [file: 
'/Users/jaisanas/work/backend/deps/cowboy/src/cowboy_websocket.erl', line: 471]}, {:cowboy_http, :loop,
 2, [file: '/Users/jaisanas/work/backend/deps/cowboy/src/cowboy_http.erl', line: 233]}, {:proc_lib, 
:init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]}

and here is my mix.exs file:

      {:phoenix, "~> 1.4.0"},
      {:phoenix_pubsub, "~> 1.1"},
      {:phoenix_ecto, "~> 4.0"},
      {:ecto_sql, "~> 3.0"},
      {:postgrex, ">= 0.0.0"},
      {:gettext, "~> 0.11"},
      {:jason, "~> 1.0"},
      {:plug_cowboy, "~> 2.0"},
      {:httpoison, "~> 1.4"},
      {:poison, "~> 3.1"}

On this thread github said that i have to delete rm -rf _build. But it still return error, anyone have a clue how to solve this error ?

Your issue seems to be due to Jason decoding:

{%Jason.DecodeError
{data: "{   \"topic\": \"room:marketplace_disbursement_service\",   \"event\": \"inquiry_response\", 
  \"payload\": {},   \"ref\": 0 }", position: 2, token: nil}

I donā€™t see anything obviously wrong in that JSON, but presumably if you take the JSON in data generated from you application and run Jason.decode!/1 on that JSON, youā€™ll get the same error. Iā€™d start removing parts of the JSON until it started working to pinpoint what is causing it to be invalid.

I think the problem is that the OP is not generating the JSON. The JSON is generated by the implementation of Phoenix Channel.

Theyā€™re responsible for the values of topic and event. But yes, if the issue isnā€™t in that part, it seems likely a bug in Jason.

Seems to parse fine:

iex(1)> Jason.decode "{   \"topic\": \"room:marketplace_disbursement_service\",   \"event\": \"inquiry_response\", 
...(1)>   \"payload\": {},   \"ref\": 0 }"
{:ok,
 %{
   "event" => "inquiry_response",
   "payload" => %{},
   "ref" => 0,
   "topic" => "room:marketplace_disbursement_service"
 }}

Iā€™ve got no idea then

Hi guys, thanks for yor help, finally i have found the solution. The problem is my jason contains tab character. So what i have to do is just clear any additional character like newline or tab from:

"{   \"topic\": \"room:marketplace_disbursement_service\",   \"event\": \"inquiry_response\",   \"payload\": {},   \"ref\": 0 }"

to this one:

"{\"topic\":\"room:marketplace_disbursement_service\",\"event\":\"inquiry_response\",\"ref\":0}"

and it works , thanks guys for helping me that the problem is jason

1 Like

That does look like a bug if Jason doesnā€™t accept 0x09 as whitespace character. The JSON standard certainly suggests it should be valid. Perhaps submit a bug report?

It seems discourse replaces the 0x09 with space characters which is why my copy/paste of your snippet parsed ok.

1 Like

I canā€™t reproduce your issue. Could you create a gist of the string that has the issue?

Jason.decode! "{\t\r\n\"hello\"\t\r\n:\t\r\n\"bye\"\t\r\n}"
#=> %{"hello" => "bye"}

Here is the way you reproduce, open your sublime, and create some messy json string with tab, like this one

"    {    \"a\": \"first\"    , \"b\": \"last\",        \"c\": {}        }"

and run it on your interactive shell like below:

>  a = "    {    \"a\": \"first\"    , \"b\": \"last\",        \"c\": {}        }"
>  require Jason
> Jason.decode(a)

and you will get output like below:

{:error,
 %Jason.DecodeError{
   data: "    {    \"a\": \"first\"    , \"b\": \"last\",        \"c\": {}        }",
   position: 0,
   token: nil
 }}

Copy/pasted what you put and it works fine:

iex()50> a = "    {    \"a\": \"first\"    , \"b\": \"last\",        \"c\": {}        }"
"    {    \"a\": \"first\"    , \"b\": \"last\",        \"c\": {}        }"
iex()51> Jason.decode(a)
{:ok, %{"a" => "first", "b" => "last", "c" => %{}}}

Throwing in some random tabs is still fine too:

iex()52> a = " \t   {  \t  \"a\": \t\"first\"  \t  ,\t \"b\": \"last\",     \t   \"c\": {} \t
 }"
" \t   {  \t  \"a\": \t\"first\"  \t  ,\t \"b\": \"last\",     \t   \"c\": {} \t       }"
iex()53> Jason.decode(a)
{:ok, %{"a" => "first", "b" => "last", "c" => %{}}}

Are you ā€˜sureā€™ your IDE/sublime is not adding in some weird invalid unicode stuff or so? What if you take your not-working json string and assign it to a then run this:

inspect(a, binaries: :as_binaries)

What is the result of that please? :slight_smile:

1 Like

Out of curiosityā€¦

What version has been picked? Could you please take a look at your mix.lock?

it returns like below:

"<<123, 32, 194, 160, 194, 160, 34, 116, 111, 112, 105, 99, 34, 58, 32, 34, 114, 111, 111, 109, 58, 109, 97, 114, 107, 101, 116, 112, 108, 97, 99, 101, 95, 100, 105, 115, 98, 117, 114, 115, 101, 109, 101, 110, 116, 95, 115, 101, 114, 118, ...>>"
1 Like

<<194, 160>> is U+00A0, a no breaking space.

According to RFC 7159 it is not valid whitespace:

      ws = *(
             %x20 /              ; Space
             %x09 /              ; Horizontal tab
             %x0A /              ; Line feed or New line
             %x0D )              ; Carriage return
4 Likes