报错:UnhandledPromiseRejectionWarning
来源:7-2 HttpBasicAuth传递令牌

qq_野火燎原_0
2020-03-12
提示是在model/user.js报错:
(node:9716) UnhandledPromiseRejectionWarning: Error
at Function.verifyEmailPassword (D:\study\island\app\model\user.js:14:13)
(node:9716) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a
catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:9716) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
我断点调试,发现是没有捕获异常,导致。可是在全局全了异常捕获,但实际上是没有去执行,不知道是怎么回事,需要怎么解决。
下面是涉及到的主要代码:
api/v1/token.js
const Router = require('koa-router')
const { TokenValidator } = require('../../validators/validator')
const { loginType } = require('../../lib/enum')
const { User } = require('../../model/user')
const router = new Router({
prefix: '/v1/token'
})
// 获取token
router.post('/', async ctx => {
const v = await new TokenValidator().validate(ctx)
// 根据不同type,来处理不同的登录方式
const type = v.get('body.type')
switch (type) {
case loginType.USER_EMAIL:
emailLogin(v.get('body.account'), v.get('body.secret'))
break;
case loginType.USER_MINI_PROGRAM:
break;
default:
break;
}
})
async function emailLogin(account, secret) {
const user = await User.verifyEmailPassword(account, secret)
}
module.exports = router
model/user.js
const { Model, DataTypes } = require('sequelize')
const bcrypt = require('bcryptjs');
const { sequelize } = require('../../core/db')
class User extends Model {
static async verifyEmailPassword(email, plainPassword) {
const user = await User.findOne({
where: {
email
}
})
if (!user) {
throw new global.errs.AuthFailed('账号不存在');
}
const correct = bcrypt.compareSync(plainPassword, user.password)
if (!correct) {
throw new global.errs.AuthFailed('密码不正确')
}
return user
}
}
User.init(
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
nickname: DataTypes.STRING(128),
email: {
type: DataTypes.STRING(128),
unique: true
},
password: {
type: DataTypes.STRING,
set(value) {
const salt = bcrypt.genSaltSync(10); // 10: 盐的复杂度,数字越大,密码越复杂,计算成本也越高
const psw = bcrypt.hashSync(value, salt)
this.setDataValue('password', psw)
}
},
openid: {
type: DataTypes.STRING(64),
unique: true
}
},
{ sequelize, tableName: 'user' }
)
// 将数据模型创建到数据库
sequelize.sync({
// force: true
})
module.exports = { User }
validators/validator.js
const { LinValidator, Rule } = require('../../core/lin-validator-v2')
const { User } = require('../model/user')
const { loginType } = require('../lib/enum')
class PositiveIntegerValidator extends LinValidator {
constructor() {
super()
this.id = [
new Rule('isInt', '需要是正整数', {
min: 1
})
]
}
}
class RegisterValidator extends LinValidator {
// email password1, password2, nickname
constructor() {
super()
this.email = [
new Rule('isEmail', '不符合邮箱规范')
]
this.password1 = [
new Rule('isLength', '密码至少6位,最多32位', { min: 6, max: 32 }),
new Rule('matches', '密码不符合规范', /^[\w]{6,32}$/)
];
this.password2 = this.password1
this.nickname = [
new Rule('isLength', '昵称长度限制在4-32位', {min: 4, max: 128})
]
}
validatePassword(vals) {
const { password1, password2 } = vals.body
if (password1 !== password2) {
throw new Error('密码输入不一致')
}
}
async validateEmail(vals) {
const { email } = vals.body
const user = await User.findOne({
where: {
email
}
})
if (user) {
throw new Error('邮箱已存在')
}
}
}
class TokenValidator extends LinValidator {
constructor() {
super()
this.account = [
new Rule('isLength', '不符合账号规范', {min: 4, max: 32})
]
this.secret = [
new Rule('isOptional'),
new Rule('isLength', '密码长度为6-32位', {min: 6, max: 32})
]
}
validateLoginType(vals) {
const { type } = vals.body
if (!type) {
throw new Error('type是必须参数')
}
if (!loginType.isThisType(type)) {
throw new Error('type参数不合法')
}
}
}
module.exports = {
PositiveIntegerValidator,
RegisterValidator,
TokenValidator
};
core/http-exception.js
class HttpException extends Error {
constructor(msg = '服务器异常', errorCode = 10000, code = 400) {
super()
this.msg = msg
this.errorCode = errorCode
this.code = code
}
}
class ParameterException extends HttpException {
constructor(msg = '参数错误', errorCode = 10000) {
super()
this.code = 400
this.msg = msg
this.errorCode = errorCode
}
}
class Success extends HttpException {
constructor(msg = 'ok', errorCode = 200) {
super()
this.code = 200
this.msg = msg
this.errorCode = errorCode
}
}
class NotFound extends HttpException {
constructor(msg = '资源未找到', errorCode = 404) {
super()
this.code = 404
this.msg = msg
this.errorCode = errorCode
}
}
class AuthFailed extends HttpException {
constructor(msg = '授权失败', errorCode) {
super()
this.code = 401
this.msg = msg
this.errorCode = errorCode
}
}
module.exports = {
HttpException,
ParameterException,
Success,
NotFound,
AuthFailed
};
lib/enum.js
const isThisType = function (val) {
for (let key in this) {
if (this[key] === val) {
return true
}
}
return false
}
const loginType = {
USER_MINI_PROGRAM: 100,
USER_EMAIL: 101,
USER_MOBILE: 102,
ADMIN_EMAIL: 300,
isThisType
}
module.exports = {
loginType
}
core/db.js
const { Sequelize, Model, DataTypes } = require('sequelize');
const { database, user, password, host, port } = require('../config/config').database
const sequelize = new Sequelize(database, user, password, {
dialect: 'mysql',
host,
port,
logging: true,
timezone: '+08:00',
define: {
underscored: true,
freezeTableName: false,
timestamps: true,
paranoid: true
}
})
module.exports = {
sequelize
};
写回答
1回答
-
qq_野火燎原_0
提问者
2020-03-12
后面通过调试,发现这个异常,只能通过一层层地往上抛,到api路由里才可能被全局异常中件件拦截到。
具体代码如下:
api/v1/token.js:
const Router = require('koa-router') const { TokenValidator } = require('../../validators/validator') const { loginType } = require('../../lib/enum') const { User } = require('../../model/user') const router = new Router({ prefix: '/v1/token' }) // 获取token router.post('/', async ctx => { const v = await new TokenValidator().validate(ctx) // 根据不同type,来处理不同的登录方式 const type = v.get('body.type') switch (type) { case loginType.USER_EMAIL: try { await emailLogin(v.get('body.account'), v.get('body.secret')) } catch (error) { throw new global.errs.AuthFailed(error); } break; case loginType.USER_MINI_PROGRAM: break; default: throw global.errs.ParameterException('没有相应的处理函数'); } }) async function emailLogin(account, secret) { try { const user = await User.verifyEmailPassword(account, secret) } catch (error) { throw error } } module.exports = router
model/user.js:
const { Model, DataTypes } = require('sequelize') const bcrypt = require('bcryptjs'); const { sequelize } = require('../../core/db') class User extends Model { static async verifyEmailPassword(email, plainPassword) { const user = await User.findOne({ where: { email } }) console.log(global.errs); if (!user) { throw new global.errs.AuthFailed('账号不存在') } const correct = bcrypt.compareSync(plainPassword, user.password) if (!correct) { throw new global.errs.AuthFailed('密码不正确'); } return user } } User.init( { id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true, }, nickname: DataTypes.STRING(128), email: { type: DataTypes.STRING(128), unique: true }, password: { type: DataTypes.STRING, set(value) { const salt = bcrypt.genSaltSync(10); // 10: 盐的复杂度,数字越大,密码越复杂,计算成本也越高 const psw = bcrypt.hashSync(value, salt) this.setDataValue('password', psw) } }, openid: { type: DataTypes.STRING(64), unique: true } }, { sequelize, tableName: 'user' } ) // 将数据模型创建到数据库 sequelize.sync({ // force: true }) module.exports = { User }
想问问,这跟老师的写法是一样的,为什么会出现这种情况,有什么好的解决办法吗,这个问题困扰我一天了
162020-03-15
相似问题