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