You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase可调用HTTPS云函数错误信息无法传递至前端的问题咨询

Firebase可调用HTTPS云函数错误处理问题

我有一个用于创建新联系人卡片的可调用HTTPS云函数,创建前需要检查是否存在相同手机号的联系人卡片,若存在则终止流程并向前端传递错误信息。但我在Firebase文档里找不到有效的错误处理方法(相关链接均指向404页面),试过Promise.reject(new Error("My error message"))和throw new functions.https.HttpsError(err.code, err.message, { message: err.message });等配置都无效,想知道正确的语法是什么?

前端调用代码

const createNewContact = useCallback(
  async (
    newContactData: NewContactData,
    successCb: () => void,
    errorCb: (err: string) => void
  ) => {
    try {
      const contact= {
        phone_number: newContactData.phone_number,
        ...other data
      };

      const createContactCF = httpsCallable(functions, "createContact");
      await createContactCF(contact);

      successCb();
    } catch (err) {
      errorCb(err.message);
      console.log("Creating a new contact failed: ", err, err.message);
    }
  },
  [user]
);

云函数代码

exports.createContact = functions.https.onCall(async (data, context) => {
  const phoneNumber = data["phone_number"];

  if (!context.auth) {
    return Promise.reject(new Error("Only authenticated users can create a new contact"));
  }

  try {
    const snapshot = await db
      .collection("contacts")
      .where("phone_number", "==", phoneNumber )
      .get();

    if (!snapshot.empty) {
      return Promise.reject(new Error("Contact with the same phone number already exists"));
    }

    const newContactDoc = db.collection("contacts").doc();
    const newContact = await newContactDoc.set(data);


    return newContact;
  } catch (err: any) {
    throw new functions.https.HttpsError(err.code, err.message, {
      message: err.message,
    });
  }
});

正确的错误处理实现方式

核心规则

可调用HTTPS云函数必须使用functions.https.HttpsError抛出业务错误,不能用Promise.reject(new Error())——Firebase对可调用函数的错误格式有严格要求,非HttpsError的错误会被封装成通用执行错误,前端无法直接获取自定义消息。

HttpsError的第一个参数必须是Firebase预定义的错误码,常用包括:

  • 'unauthenticated':用户未认证
  • 'already-exists':资源已存在
  • 'invalid-argument':参数无效
  • 'internal':系统内部错误

修改后的云函数代码

exports.createContact = functions.https.onCall(async (data, context) => {
  const phoneNumber = data["phone_number"];

  // 认证检查:抛出未认证错误
  if (!context.auth) {
    throw new functions.https.HttpsError('unauthenticated', '仅认证用户可创建联系人');
  }

  try {
    const snapshot = await db
      .collection("contacts")
      .where("phone_number", "==", phoneNumber )
      .get();

    // 手机号重复检查:抛出资源已存在错误
    if (!snapshot.empty) {
      throw new functions.https.HttpsError('already-exists', '该手机号对应的联系人已存在');
    }

    const newContactDoc = db.collection("contacts").doc();
    await newContactDoc.set(data);

    return { id: newContactDoc.id, ...data };
  } catch (err: any) {
    // 区分业务错误与系统错误
    if (err instanceof functions.https.HttpsError) {
      throw err;
    }
    // 系统错误统一用internal码封装
    throw new functions.https.HttpsError('internal', '创建联系人时发生系统错误', {
      originalError: err.message
    });
  }
});

前端错误处理优化

可调用函数抛出的HttpsError包含code、message、details三个核心属性,前端可精准处理不同错误场景:

const createNewContact = useCallback(
  async (
    newContactData: NewContactData,
    successCb: () => void,
    errorCb: (err: string) => void
  ) => {
    try {
      const contact= {
        phone_number: newContactData.phone_number,
        ...other data
      };

      const createContactCF = httpsCallable(functions, "createContact");
      await createContactCF(contact);

      successCb();
    } catch (err: any) {
      const errorMessage = err.message || '创建联系人失败,请稍后重试';
      errorCb(errorMessage);
      // 可根据错误码做针对性处理
      if (err.code === 'already-exists') {
        // 例如:显示手机号重复的专属提示
      }
      console.log("创建联系人失败: ", err.code, errorMessage);
    }
  },
  [user]
);

内容的提问来源于stack exchange,提问作者Tsabary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:13:19