Check! Azure Functions で Node.js で書いてるのに .NET Framework のエラーが発生するときのヒント(出力バインド)

  • 1
    いいね
  • 0
    コメント

こんにちは、 @dz_ こと大平かづみです。

Prologue - はじめに

Azure Functions で、Node.js で書いたコードを再び動かしたところ、以下のエラーで動かなくなってしまいました。

ファンクションの実行自体は終わってるようなのに、 mscorlib: Buffer cannot be null. Parameter name: buffer. という見慣れないエラーが発生しています。

途方に暮れていましたが、原因と解決方法がわかったので記録します。

エラー内容

2017-02-08T10:30:00.005 Function started (Id=ebc259da-f172-4c93-a58f-f83605cd1df8)
2017-02-08T10:30:27.857 Function completed (Failure, Id=ebc259da-f172-4c93-a58f-f83605cd1df8)
2017-02-08T10:30:27.857 Exception while executing function: Functions.TimerTriggerJS1. mscorlib: Buffer cannot be null.
Parameter name: buffer.

発生環境

関数の処理は、データベースから読み出した JSON データを Azure Blob Storage に保存するものです。

調査結果

この mscorlib: Buffer cannot be null. Parameter name: buffer. は、どうやら .NET Framework の環境で発生する汎用的なエラーメッセージのようで、なかなか原因を特定できませんでした。

しかし、ファンクションの処理自体は終わっていることに着目すると、どうやら Node.js の処理ではなく、 Azure Functions 側で起こってるようです。

ファンクション実行完了後に処理されるのは… 私が設定していた「出力バインド」。

これだ!

結論

私の処理では、Storage BLOB の出力バインドに JSONオブジェクト を渡していました。

Azure Functions は、Storage BLOB にオブジェクトを出力すると、シリアル化してテキストファイルとして保存してくれます。

どうやら、渡した JSONデータが膨大すぎて、シリアル化でコケていたようです。

サンプル
module.exports = function(context) {
    // 出力する JSONデータを取得する
    var jsonData = getJsonData();

    // ★ BLOB 出力バインドに渡す (※だがしかし、オブジェクトが大きすぎた)
    context.bindings.myOutputBlob = jsonData;
    context.done();
};

そこで試しに、先に JSON.stringify() で文字列化してから渡してあげると、無事出力されるようになりましたとさ♪

改良後のサンプル
module.exports = function(context) {
    // 出力する JSONデータを取得する
    var jsonData = getJsonData();

    // ★ 文字列型に変換してから、 BLOB 出力バインドに渡す
    context.bindings.myOutputBlob = JSON.stringify(jsonData);
    context.done();
};

ちなみに、当初はデータの少ない状態だったため発生しなかったが、しばらくしてデータが増えた後に実行したことにより発覚ということでした。(実運用前でよかったw)

めでたしめでたし (。・ω・)ノ

Epilogue - おわりに

このエラー、わかってしまえば簡単なことだったんですが、数日悩んでました。無事解決してほっとしてます。

今回は、BLOB でしたが、別の出力でも同様の状況がありそうです。プラットフォームやフレームワーク側に負担をかけない処理を心がけねばなりませんね!