Firebase - 如何扩展 FirebaseError?

Firebase - How to extend FirebaseError?

我正在实现一个使用唯一用户名和密码注册的云功能。

为了抛出异常,我之前做了以下操作:

signUpValidation.js

if (!validateUsername(username)) {
  throw new functions.https.HttpsError(
    "invalid-argument",
    "Invalid username.",
    {
      status: "error",
      code: "auth/invalid-username",
      message: "Username must be between 3 and 30 characters, including numbers, letters, hyphens, periods, or underscores.",
    }
  );
}

signUp.function.js

try {
  await validateSignUpData(
     username,
     email,
     password,
     repeatPassword,
     name,
     birthday,
     clientIp
  );
} catch(err) {
    if (err instanceof functions.https.HttpsError) {
      throw err;
    }

    // An unknown error has occurred
    console.error(err);

    throw new functions.https.HttpsError(
      "unknown",
      "Unexpected error.",
      { 
        status: "error",
        code: err.code ?? "unknown",
        message: err.message ?? "The registration request could not be processed. Please, try again later."
      }
    );
}

但是,我不太喜欢这种在 signUpValidation 模块中抛出异常的方式……抛出“AuthErrors”而不是“HttpsErrors”对我来说更有意义。

因此,由于似乎无法扩展默认的 Firebase 错误,我决定创建自己的 util/authErrors 模块:

class AuthError extends Error {
  constructor(code, message) {
    super(message);
    this.code = code;
    this.name = "AuthError";
  }
}

const authErrors = Object.freeze({
  usernameAlreadyExists(message = "The username is already in use by an existing account") {
    return new AuthError('auth/email-already-exists', message);
  }

   ... more errors
});

module.exports = authErrors;

如您所见,我已经为每种错误类型创建了自定义错误和一些工厂函数。然后,在我的 signUpValidation.js 中,我只做:

if (!(await isUsernameUnique(username))) {
  throw authErrors.usernameAlreadyExists();
}

是否可以扩展 FirebaseError?如果不是,为什么?

为了在 Cloud Functions 中抛出自定义异常,以这种方式工作是否被认为是一种不好的做法?我的意思是,我应该只抛出 HttpsErrors 吗?

如果您要以不同的方式对待它,拥有自定义错误类型会很有用。 例如,如果您有一个 try/catch 块并希望为您的自定义错误设置不同的逻辑。 但是在这里您将错误传递给不知道 Firebase HttpsError 或您的自定义 AuthError 的客户端。因为最后你的对象将被序列化为 JSON 而在另一端没有 class 将它转换回 HttpsError 或 AuthError.

同样在 HTTP 协议级别,身份验证错误由 HTTP 状态代码(例如 401、403)定义,因此它们本质上不是不同的对象类型。 我的意思是,当您的服务器端无法转换自定义 AuthError class 时,我看不出有任何优势,因为它对您的客户端来说是不同的。 对于客户端,HTTP 状态代码是区分 Auth 错误和其他类型错误的关键。