JSON.stringifyが空要素をNULLに変換するようになってハマる

倒れるプログラムのキャラクター
ニコニコ動画の視聴履歴を記録しつつ紹介しているサイト「1日1ニコ」の投稿フォームが500エラーで動かなくなって1週間ほど空いてしまいました。なんだったんだ?






問題はこれでした

タイトルに原因書いちゃってますけど、これがわかるまでものすごく大変でした。まったくわかんなくて。プログラムはこんな感じになってました。

Post.vue

axios.post('/api/nico/post',{
   data: JSON.stringify(this.form)
})

NicoPostController.php

$content .= $this->_convertASINToContent($data->asin);

private function _convertASINToContent($asin)
{
   if($asin == '') {
       return '';
   }
   //略
}


フォームの「asin」が空だった場合、今までなら受け取った側でも空になっていたので、_convertASINToContentメソッドが空を返していたんですけど、いつの頃からか空要素がnullに変換されるようになってしまっていました。そののため_convertASINToContentの先の処理に進んでしまってエラーになっていたんですね。マジか。



対応後

NicoPostController.php

$content .= $this->_convertASINToContent($data->asin);

private function _convertASINToContent($asin)
{
   if(!$asin) {
       return '';
   }
   //略
}


正直 !$asin で比較するのは好きじゃないんですけど(特にPHPは色々アレなので)、今回の場合は !$asin の判定対象になるような文字列が入ってたらそもそもアウトなので、まあ良いんじゃないかと思います。直って良かった。



ほんとに大変だったんですよ

ローカルじゃエラーにならないので、本番環境のソースコードにdump処理を入れてPOSTリクエストできるツールで確認しながら、「どこまで正常でどこでダメになっているのか」を1つずつ潰していきました。しかも悪いことにログファイルのパーミッションのせいで「例外が投げられてログを記録しようとしても500を返す」という状況になっていて、初期段階ではどこが問題なのかまったく見分けがつかず。ログファイルのパーミッションに気付いてからは調査が一気に進んだので、いやあ、いろいろな可能性を考えるって大事ですね。


しかしこれ、ホントに何だったんだろう。いきなり来たんだよなあ……Chromeの更新のせいとしか思えないんだが。