未踏作業日誌――余計なもの作るよ!

未踏の作業日誌的なものを書きましょうということで書くことにしました.余計なことばっかりしています.

Sinatra(+Sequel)でInternal Server Errorになる問題

プログラム的にどこも間違っていないはずなのにSinatraInternal Server Error (can't convert Array into String)を返すようになって,1時間ほど頭を働かせていた.どうしても解決しないと思ったら意外なところにあった.

 

Sinatraはgetやpostと呼ばれるメソッドにブロックを渡してRailsのようなルーティングを行っている.基本的には最後に評価された文字列がブラウザに送信される仕組みになっている.

ただし,当然ながら最後に評価されるモノが異なると,Sinatraではどのように解釈していいのかわからなくなる.例えば,最後に評価されたのが配列だと,サーバに配列が渡され,どのような文字列をブラウザに送信すればいいのかわからなくなってしまう.

Sinatraで発生するInternal Server Error (特にcan't convert Array into String)は,最後に評価されたものが配列だった,というオチで,どこもこういうことを解説していないので誰しもが一度はハマる有り様になっている.

 

例えば,以下の様なコードはハマる.

gist9309359

一見すると,最後に評価されるのはTag.createかもしれないが,どうやら配列が返ってきているらしい.これだとInternal Server Errorで落ちるので,最後にきちんと文字列を渡してあげる必要がある.

一体,どこで配列が返ってきてしまっているのか皆目検討もつかないが,これはこれでしょうがない.配列が返ってきているという事実だけがある.

こういうフレームワーク的な問題は,どうしても経験則的なものが必要になってくるため,作っていて面倒くさいと感じる.普通ならば型が評価されてインスタンスのIDでもなんでもここで表示されるはずなのだが,このようにbegin-rescueで囲った場合は例外のようだ.注意しないとハマる.