jsonが壊れた!!

解いた人:maimai-y

参照した問題・解説のサイト:jsonが壊れた!!

使用環境・ツール

  • Go
  • json

問題文でされた操作

GoでAPIサーバを作った。

バグの内容

json文字列をparseするときにデータがlossしてしまう。

初期状態

VM名 gogo には、golang 1.14.6がインストールされている。 VMのホームディレクトリにはtestcode.go が置かれている。

$ go run testcode.go を実行すると以下の結果が得られる。

  • 実行結果
{10 Gopher 0}

理想の終了状態

コマンド $ go run testcode.go を実行すると

{10 Gopher passwordnohash 99}

上記の結果が得られる。

また、問題の解決が永続化されている。


考えられる検証、修正手順

バグの原因を特定する案

  • testcode.goの問題
    • 構造体とJSONの構造をそろえて定義してあるか確認する
    • nullがjsonに含まれていたときのことを考慮しているか確認する
      • バージョンによって、nullがjsonに含まれていると扱い方によってはエラーになる
      • はてブ
    • 文字コード周りを確認する
      • jsonの仕様的に文字列の中に'\n'を含んではいけない
      • はてブ
    • floatとint周りを確認
      • GoはJSONの中に含まれる数値を float64 型として扱う
      • qiita
  • jsonの問題
    • 形式がおかしくないか確認する

バグの原因が見つかった際の手順

  • testcode.goの問題
    • testcode.goを修正
  • jsonの問題
    • jsonを修正

修正手順案

  • エラーメッセージを読むと、testcode.goの問題のポツで書いた4つの原因のどれか、またはそれ以外かが分かる

  • もしエラーメッセージに情報が無ければ、ひとまずtestcode.goを確認した後、jsonを地道に確認


解説

原因

この問題はUserという構造体のtag指定が2点間違っていることが原因でした。

コンパイルでは見つけられない。

1

=を:に修正する。


変更前

json=""

変更後

json:""

実行結果

{10 Gopher passwordnohash 0}

2

“が抜けているため足す。


変更前

"access_count`

変更後

"access_count"`


・2だけを修正した場合

{10 Gopher 0}

・1と2を修正した場合

{10 Gopher passwordnohash 99}

解法2

go vet コマンドによる静的解析

  • go vetとは?
    • 本当に問題になるかは分からないし、ビルドは通せるんだけど、こういう懸念があるかもね 的な問題を コンパイラとは別の観点でチェックしサジェストをしてくれる、賢い子
    • qiita