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 错误和其他类型错误的关键。
我正在实现一个使用唯一用户名和密码注册的云功能。
为了抛出异常,我之前做了以下操作:
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 错误和其他类型错误的关键。