首页 > 解决方案 > 如何从 Google Firebase 函数中的失败承诺返回自定义错误消息?

问题描述

我制作了一个 Firebase 云函数来创建一个新用户(我正在制作一个自定义函数而不是使用firebase.auth().createUserWithEmailAndPassword,因为我想在创建时为用户添加额外的数据)。我想在 promise 被拒绝时显示自定义错误消息,或者至少保留原始 Firebase 错误消息(如果发生诸如电子邮件地址已被使用等情况)。但是,现在每当 promise 被拒绝时,客户端只能看到 a 500 Internal Server Error,这对最终用户没有多大帮助。我认为这是按照Firebase 文档的预期发生的

如果调用了可调用触发器,但由于未处理的异常而失败或返回失败的承诺,则请求将被拒绝并返回 500 Internal Server Error,错误代码为 INTERNAL。这可以防止编码错误意外暴露给最终用户。

有没有一种好方法可以在云函数中保留原始错误消息,而不会默认为 500 错误?我想我可以在块中编写自己的错误处理catch来“解决”我想向用户显示的错误,但这似乎是一个混乱的解决方案......有什么想法吗?我的代码如下:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

const serviceAccount = require('./serviceAccount.json');
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);

exports.createUser = functions.https.onCall((data, context) => {
    return new Promise((resolve, reject) => {
        const { name, email, password } = data || {};
        if (!name || name.length > 50 || /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(email) === false || password.length < 8) {
            reject(new Error("Invalid data"));
        }
        else {
            resolve(admin.auth().createUser({
                email,
                password,
                displayName: name
            }));
        }
    });
});

编辑——下面的答案解决了我的问题;这是我更新的代码,以防其他人有类似的需求:

exports.createUser = functions.https.onCall((data, context) => {
    return new Promise((resolve, reject) => {
        const { name, email, password } = data || {};
        if (!name || name.length > 50 || /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(email) === false || password.length < 8) {
            reject(new functions.https.HttpsError('invalid-argument', 'Invalid data'));
        }
        else {
            admin.auth().createUser({
                email,
                password,
                displayName: name
            })
            .then( res => resolve(res))
            .catch( err => reject(new functions.https.HttpsError('failed-precondition', err.message || 'Internal Server Error')))
        }
    });
});

标签: javascriptfirebasegoogle-cloud-functions

解决方案


文档建议您应该抛出一个带有信息的HttpsError以发送给客户端。字符串代码将被转换为 HTTP 状态代码,您传递的消息也将可用。


推荐阅读