如何解决在各种检查的过程中, 记录返回的错误code,并且返回给前端
以前是直接 return
function(req, res) {
var user = req.body;
if (!user.username) {
return res.json({
msg: 'no username',
code: 1
});
}
if (!user.password) {
return res.json({
msg: 'no password',
code: 2
});
}
if (!user.code) {
return res.json({
msg: 'no code',
code: 3
});
}
return checkCode(user)
.then(function(data) {
return checkPassword(user);
})
.then(function() {
return res.json({
msg: 'login success'
});
})
.catch(function(err) {
console.warn(err);
return res.json({
msg: 'login fail',
code: 4
});
});
}
但是如果用 Promise
包装过后, return
只是到下一个 Promise
, 下面的写法 在bb3.0+ 中会 warning Promise.reject
需要一个error
有没有一种比较好的解决方式呢?
function(req, res) {
var user = req.body;
return Promise
.resolve(function() {
if (!user.username) {
return Promise.reject({
msg: 'no username',
code: 1
});
}
if (!user.password) {
return Promise.reject({
msg: 'no password',
code: 2
});
}
if (!user.code) {
return Promise.reject({
msg: 'no code',
code: 3
});
}
return checkCode(user)
.then(function(data) {
return checkPassword(user);
});
})
.then(function() {
return res.json({
msg: 'login success'
});
})
.catch(function(err) {
/**
err 可能是 no password 或者 no code 等各种错误
**/
return res.json(err);
});
}
先去好好看看promise吧
来自酷炫的 CNodeMD
按你这种写法,也没有问题,只是会报warning。如果想不报warning的话,Promise.reject(new Error(‘这里面定义你的错误’))
@imhered new Error 的话, 不能同时存储 msg 和 code了, 有没有更好的办法?
@iyuq 说了等于没说, 连哪里问题都不说明?
@xinshangshangxin 没用更好的办法了,就让他warning吧,我现在全都是reject的或者throw
@imhered 谢谢!
let err = new Error('你的错误消息');
err.status = 400;
return Promise.reject(err);
这样就既有code又有message了。也可以自己写一个创建err的函数:function createError(status, message)
可以继承 Promise.OperationalError ,把 code 加进去,然后 Promise.reject(new MyError(CODE, MSG)) 。不要通过另一个 function 创建,这样可以快速定位 reject 发生的位置,然后在 error 里面统一捕获再返回 res.json
来自酷炫的 CNodeMD
@klesh 谢谢!
@klesh 是这样吗? 但是 快速定位 reject 发生的位置
没有理解
var util = require('util');
var Promise = require('bluebird');
var myError = function(code, message) {
this.code = code;
this.message = message;
};
util.inherits(myError, Promise.OperationalError);
Promise
.resolve()
.then(function() {
return Promise.reject(new myError(400, '123'));
})
.catch(function(e) {
// { [Error: 123] code: 400, message: '123' }
console.log(e);
});
@iyuq 谢谢, 但是这样写是不是有些绕圈子? 在实际开发中是怎么处理的呢?
用 async await 吧,promise 解决不了嵌套问题。
为什么要这么写代码 硬生生把不是异步的部分也扯进Promise里去 我习惯这么干:
function checkCode(code) {
return new Promise(funtion(resolve, reject) {
// todo
if(true) resolve()
else reject(err)
})
}
function checkPassword(pass) {
return new Promise(funtion(resolve, reject) {
// todo
if(true) resolve()
else reject(err)
})
}
function(req, res) {
// 上面的不变
checkCode(user)
.then(checkPassword)
.catch(err) {
res.json({code: 4, msg: err})
}
}
在请求的handler里边返回Promise是没有啥意义的。
@chemdemo 首先谢谢回答!
但是问题的重点不再这块
重点是: 对于 “no username” 的code为 1
对于 "no password"的code为2
对于 "验证码错误"的code为3
所以我希望得到一个 promise reject中 同时带有 errCode 和 errMsg的
你的写法 code只有一个了
checkCode(user)
.then(checkPassword)
.catch(err) {
res.json({code: 4, msg: err})
}
问题是: 如何区分多种错误, 返回是带上errCode 和 errMsg
@285858315 还没有标准化, 不准备用babel
你现在的情况比较简单,但随着应用越来越复杂。可能会出现a使用了b,b使用了c,c使用了d,d reject了。a却忘了处理error, 这时bluebird能打印出原始的stack信息以及reject发生的位置。那一眼就能明白问题出在哪里了。
来自酷炫的 CNodeMD
@klesh 这个方法好像很好呢,这样reject的时候就不会warning了
@klesh 大概懂了, 谢谢!!!
var util = require('util');
var Promise = require('bluebird');
var MyError = function(code, message) {
this.code = code;
Promise.OperationalError.call(this, message);
};
util.inherits(MyError, Promise.OperationalError);
function myError2(code, message) {
var e = new Error(message); //默认报错在这里
e.code = code;
return e;
}
function MyError3(code, message, constr) {
Error.captureStackTrace(this, constr || this); // 默认报错在这里
this.code = code;
this.message = message || 'Error'
}
util.inherits(MyError3, Error);
Promise
.resolve()
.then(function() {
return Promise.reject(new MyError(400, '123')); //默认报错在这里
});
Promise
.resolve()
.then(function() {
return Promise.reject(myError2(400, 'test')); //默认报错在 myError2 内部
});
Promise
.resolve()
.then(function() {
return Promise.reject(new MyError3(400, 'test'));//默认报错在 MyError3 内部
});