如何抛出自定义错误?
How to Throw custom Errors?
我正在尝试使用 passport-jwt
策略进行身份验证。
这是我的代码:-
router.post('/register', async (req, res) => {
const { username, email } = req.body;
try {
const user = await User.findOne({ username });
if (user) {
throw new Error('User with same username already exists !!');
}
const newUser = new User({
username,
email
})
const salt = await bcrypt.genSalt(10);
newUser.password = await bcrypt.hash(req.body.password, salt);
const savedUser = await newUser.save();
res.json({
status: 200,
'Content-Type': 'Application/Json',
'message': `You have successfully regirstered yourself, ${savedUser.username}!`
})
} catch (err) {
err.statusCode = 500;
console.log(err.message);
res.header({
status: '200',
'Content-Type': 'Application/Json',
});
res.json(err);
}
});
现在这条路线工作得很好,它正在做所有的事情到现在为止。唯一的问题是,当我找到现有用户时,我想用自定义消息抛出一个新错误。 Javascript 有这个 Error
class 我可以用它来抛出这些错误。
捕获错误时出现问题。当我 console.log(err.message)
时,我可以完美地看到我的自定义消息。但是我通过 res.json(err)
作为响应 return 的 err
对象没有任何 message
,只有 statusCode
.
我想知道为什么会这样,有什么解决办法?现在,我正在通过做这样的事情来做到这一点:-
res.json({
statusCode: 500,
message : err.message
});
但我想 return err
对象同时填充 statusCode
和 message
字段。
用以下代码行替换整个 catch 块。
res.status(500).json({
message: err.message
})
来自 documentation of res.json() :此方法发送一个响应(具有正确的内容类型),该响应是使用 JSON.stringify() 转换为 JSON 字符串的参数。
现在 运行 JSON.stringify(new Error('custom msg'))
我们得到 "{}"
您正在将错误对象传递给响应对象的 json 方法。但这只需要 JSON 可解析字符串作为参数。你可以做的是使用 -
res.json(JSON.stringify(err))
并且在你使用这个响应的地方,你需要将这个字符串解析为JSON,然后将它转换成一个Error对象。假设您的前端也使用 javascript
,您可以使用以下语法
err = new Error(JSON.parse(response.data))
您可以创建自己的 Error
class,它可以在构造函数中采用多个参数。 class 必须扩展基础 Error
JavaScript class。例如:
class MyCustomError extends Error {
constructor(msg, statusCode) {
super(msg);
this.statusCode = statusCode;
this.name = MyCustomError.name;
}
}
function throwCustomError() {
throw new MyCustomError('Some custom message', 404);
}
try {
throwCustomError();
} catch (error) {
console.log(error.message);
console.log(error.statusCode);
console.dir(error);
}
Remember that you have to call super
on the beginning of the constructor if you are extending another class
我正在尝试使用 passport-jwt
策略进行身份验证。
这是我的代码:-
router.post('/register', async (req, res) => {
const { username, email } = req.body;
try {
const user = await User.findOne({ username });
if (user) {
throw new Error('User with same username already exists !!');
}
const newUser = new User({
username,
email
})
const salt = await bcrypt.genSalt(10);
newUser.password = await bcrypt.hash(req.body.password, salt);
const savedUser = await newUser.save();
res.json({
status: 200,
'Content-Type': 'Application/Json',
'message': `You have successfully regirstered yourself, ${savedUser.username}!`
})
} catch (err) {
err.statusCode = 500;
console.log(err.message);
res.header({
status: '200',
'Content-Type': 'Application/Json',
});
res.json(err);
}
});
现在这条路线工作得很好,它正在做所有的事情到现在为止。唯一的问题是,当我找到现有用户时,我想用自定义消息抛出一个新错误。 Javascript 有这个 Error
class 我可以用它来抛出这些错误。
捕获错误时出现问题。当我 console.log(err.message)
时,我可以完美地看到我的自定义消息。但是我通过 res.json(err)
作为响应 return 的 err
对象没有任何 message
,只有 statusCode
.
我想知道为什么会这样,有什么解决办法?现在,我正在通过做这样的事情来做到这一点:-
res.json({
statusCode: 500,
message : err.message
});
但我想 return err
对象同时填充 statusCode
和 message
字段。
用以下代码行替换整个 catch 块。
res.status(500).json({
message: err.message
})
来自 documentation of res.json() :此方法发送一个响应(具有正确的内容类型),该响应是使用 JSON.stringify() 转换为 JSON 字符串的参数。
现在 运行 JSON.stringify(new Error('custom msg'))
我们得到 "{}"
您正在将错误对象传递给响应对象的 json 方法。但这只需要 JSON 可解析字符串作为参数。你可以做的是使用 -
res.json(JSON.stringify(err))
并且在你使用这个响应的地方,你需要将这个字符串解析为JSON,然后将它转换成一个Error对象。假设您的前端也使用 javascript
,您可以使用以下语法err = new Error(JSON.parse(response.data))
您可以创建自己的 Error
class,它可以在构造函数中采用多个参数。 class 必须扩展基础 Error
JavaScript class。例如:
class MyCustomError extends Error {
constructor(msg, statusCode) {
super(msg);
this.statusCode = statusCode;
this.name = MyCustomError.name;
}
}
function throwCustomError() {
throw new MyCustomError('Some custom message', 404);
}
try {
throwCustomError();
} catch (error) {
console.log(error.message);
console.log(error.statusCode);
console.dir(error);
}
Remember that you have to call
super
on the beginning of the constructor if you are extending another class