#はじめに
元ネタはこちら
ある日、cloud functionsで新しい関数をデプロイしました。
すると、しっかり動作確認はできていたのに大量のエラーが発生しました。。
Error: Process exited with code 16
at process.on.code (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:275:22)
at process.emit (events.js:198:13)
at process.EventEmitter.emit (domain.js:448:20)
at process.exit (internal/process/per_thread.js:168:15)
at Object.sendCrashResponse (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/logger.js:37:9)
at process.on.err (/layers/google.nodejs.functions-framework/functions-framework/node_modules/@google-cloud/functions-framework/build/src/invoker.js:271:22)
at process.emit (events.js:198:13)
at process.EventEmitter.emit (domain.js:448:20)
at emitPromiseRejectionWarnings (internal/process/promises.js:140:18)
at process._tickCallback (internal/process/next_tick.js:69:34)
#このエラーはそもそも何?
結論から言うと、わかりません!!
だって検索しても何も情報がないんだもん。。。
#このエラーを防ぐには?
下記のコードは僕が実際にアプリで使っているものです。
userがeventを作成(というかonWrite
トリガーなので、作成、削除、更新のいずれか)したときに発動する関数で、作成したeventの数をカウントしています。
詳しくはこちら
Firebase 要素の数をカウントするなら、最初からこの方法でいきましょう!(Cloud Functions)
exports.monthCountEvents = functions.region('asia-northeast1').firestore
.document('users/{userId}/events/{eventId}')
.onWrite((change, context) => {
let pushMonths: any;
let periods: boolean;
let dayEventCounts: number;
if (!change.before.exists) {
pushMonths = change.after.get('pushMonths');
periods = change.after.get('periods');
dayEventCounts = change.after.get('dayEventCounts');
} else {
pushMonths = change.before.get('pushMonths');
periods = change.before.get('periods');
dayEventCounts = change.before.get('dayEventCounts');
}
const userId = context.params.userId;
const FieldValue = admin.firestore.FieldValue;
const monthCountRef = db.collection(`users/${userId}/counts`).doc(pushMonths);
monthCountRef.get().then((docSnapshot) => {
if (!docSnapshot.exists) {
monthCountRef.set({ monthCount: dayEventCounts, monthDate: pushMonths });
} else {
if (!change.before.exists && !periods) {
// 登録時に件数をインクリメント
monthCountRef.update({ monthCount: FieldValue.increment(dayEventCounts) });
} else if (change.before.exists && !change.after.exists && !periods) {
// 削除時に件数をデクリメント
monthCountRef.update({ monthCount: FieldValue.increment(-dayEventCounts) });
}
return;
}
// catchが重要らしい!
}).catch((error) => {
console.log("monthCountRef Error getting document:", error);
});
});
とりあえず.catch
を使うことでこの手のエラーは回避できるようです。
.catch((error) => {
console.log("monthCountRef Error getting document:", error);
});
謎な点は「エラーでまくってても、時間が経てば正常に処理されている」と言う点だろうか・・・
最初「やべー、本番環境やのにエラーでまくってる〜!!!」と焦ってたのですが、、
次の日Firestoreを見ると、エラーで実行されなかったと思われていた処理が、なんと普通に実行されていたのです。。。
つまり、cloud functionsのonWrite
トリガーで、「A」と言うdocumentを作成する処理があったとして、その処理はError: Process exited with code 16
でストップしたと思っていました。
しかし時間が経ってから見ると、「A」と言うdocumentは作成されていました。
うーん、よくわからんけどすごいぞFirebase!!!