Firestore から発生するエラーを HttpsError に変換する
概要
firestore thrown -> HttpsError への変換器を作って
ある程度汎用的に firestore のエラーをハンドリングしてしまおう。
背景
あるプロジェクトのサーバーサイドでは、
想定内のエラーが起きた時に HttpsError を throw する決まりとしている。
(throw された HttpsError は独自の共通処理により、内容に応じたステータスコードをレスポンスしている。)
firestore では、例えば存在しない document を update しようとした場合などにエラーを throw してくる。
しかし、 firestore にふれるすべての部分で、
想定内の firestore thrown -> HttpsError への変換を担うのはとてもコストが高く現実的ではない。
(本日時点では firestore thrown の型の定義が参照できないこともその一因だ。)
実装
firestore thrown ハンドラ
import { HttpsError } from "firebase-functions/lib/providers/https";
export class FirestoreHelper {
/**
* 2020/06/10 時点では、firestore が throw するエラーの型情報にアクセスできないため、
* HttpsError に生まれ変わらせるハンドラを作った。
*/
public static errorHandler(error: any) {
const isFirestoreThrown =
error.code != null || error.details != null || error.metadata != null;
if (!isFirestoreThrown) {
throw error;
}
// Code は FirebaseFirestore.GrpcStatus に基づいているが、ここからは型参照できない
switch (error.code) {
case 0: //OK = 0,
throw new HttpsError("ok", error.details);
case 1: //CANCELLED = 1,
throw new HttpsError("cancelled", error.details);
case 2: //UNKNOWN = 2,
throw new HttpsError("unknown", error.details);
case 3: //INVALID_ARGUMENT = 3,
throw new HttpsError("invalid-argument", error.details);
case 4: //DEADLINE_EXCEEDED = 4,
throw new HttpsError("deadline-exceeded", error.details);
case 5: //NOT_FOUND = 5,
throw new HttpsError("not-found", error.details);
case 6: //ALREADY_EXISTS = 6,
throw new HttpsError("already-exists", error.details);
case 7: //PERMISSION_DENIED = 7,
throw new HttpsError("permission-denied", error.details);
case 8: //RESOURCE_EXHAUSTED = 8,
throw new HttpsError("resource-exhausted", error.details);
case 9: //FAILED_PRECONDITION = 9,
throw new HttpsError("failed-precondition", error.details);
case 10: //ABORTED = 10,
throw new HttpsError("aborted", error.details);
case 11: //OUT_OF_RANGE = 11,
throw new HttpsError("out-of-range", error.details);
case 12: //UNIMPLEMENTED = 12,
throw new HttpsError("unimplemented", error.details);
case 13: //INTERNAL = 13,
throw new HttpsError("internal", error.details);
case 14: //UNAVAILABLE = 14,
throw new HttpsError("unavailable", error.details);
case 15: //DATA_LOSS = 15,
throw new HttpsError("data-loss", error.details);
case 16: //UNAUTHENTICATED = 16,
throw new HttpsError("unauthenticated", error.details);
default:
throw error;
}
}
}
ハンドラの利用例
await firestore.runTransaction(async (tx) => {
// do something...
}).catch(FirestoreHelper.errorHandler); // ⭐ here!
await firestore.collection("dragons")
.doc(dragonId)
.update(updates)
.catch(FirestoreHelper.errorHandler); // ⭐ here!
変換後の HttpsError 例
{
"message": "No document to update: projects/<YOUR_PROJECT_NAME>/databases/(default)/documents/dragons/drag_01eac5sjgnxacznztyjs2m8fzw1",
"status": "NOT_FOUND"
}
結論
- 強く意識しなくとも、 firestore エラーを汎用的に処理できるようになったぞ
- しかし、エラーメッセージに実装内容が滲み出てしまっているので注意だぞ
- firestore には早くエラー型の定義をしてほしいぞ
Author And Source
この問題について(Firestore から発生するエラーを HttpsError に変換する), 我々は、より多くの情報をここで見つけました https://qiita.com/tokicat/items/e8d2965f6e5e24d3cdbc著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .