アメッシュでECONNRESETを食らっててslackbotが死んでた件
おはようございます。次男の保護者会に行けずに、個別に面談する予定でしたが、電車の人身事故で保育園のお迎え時間もぎりぎりになり面談はなくなり、資料をもらうだけになりました。まぁ次男はうまいことやってることが予想されるのであんまり気にしてません。@kjunichiです。
背景
気づいたら、botkitで作ってHerokuにあげていたslackbotが死んでました
調査
このbotは「雨どう」と尋ねると、東京アメッシュの画像を張り付ける機能があり、 ここでエラーが起き、node.jsが死んでました。
原因
エラーの原因は、アメッシュからJPEGファイルを取得する際なぜか、通信途中でECONNRESETがかかり、 JPEGファイルの一部が欠落した状態でした。
2017-02-09T22:20:00.602972+00:00 app[web.1]: http://tokyo-ame.jwa.or.jp/mesh/000/201702100715.gif 2017-02-09T22:20:01.290589+00:00 app[web.1]: { Error: read ECONNRESET 2017-02-09T22:20:01.290599+00:00 app[web.1]: at exports._errnoException (util.js:1026:11) 2017-02-09T22:20:01.290600+00:00 app[web.1]: at TCP.onread (net.js:569:26) code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read' } 2017-02-09T22:20:03.239987+00:00 app[web.1]: Premature end of JPEG file
対策
Node.jsでの定番のハンドリングできなかった例外をキャッチして続行することで、bot自体は 死なないようにできました。
process.on('uncaughtException', function(err) { console.log(err); });
ECONNRESETへの対応
これが謎。 公式のhttp.getの解説だと
getの外でerrorをとらえてはいるが、このやり方だと、今回設定したuncaughtExceptionまでいってしまった。
また、連続して画像を取得するのが悪いのかと思い、各レイヤーごとにウェイトを入れてアクセスしてみたが、 これもダメだった。
関連記事
- Node.jsでターミナル.appにアメッシュを表示させてみた
- アメッシュの画像を表示するslackのボットをbotkitを使ってDockerイメージにしてherokuで動かした
- herokuでbotkitを動かしGoogle Calendar APIを使う
- DockerのAlpine Linuxでタイムゾーンでハマった
- herokuにデプロイしてたSlackボット(Botkitベース)を治した