目前我处理我的身份验证如下:
function login(req, res, next) {
// fetch user from the db
User.findOne(req.body)
.exec() // make query a Promise
.then((user) => {
const token = jwt.sign({ username: user.username }, config.jwtSecret);
return res.json({ token, username: user.username });
})
.catch(() => {
const err = new APIError('Authentication error', httpStatus.UNAUTHORIZED, true);
return Promise.reject(err);
});
}
我正在尝试使用常见的APIError类标准化我的错误
import httpStatus from 'http-status';
/**
* @extends Error
*/
class ExtendableError extends Error {
constructor(message, status, isPublic) {
super(message);
this.name = this.constructor.name;
this.message = message;
this.status = status;
this.isPublic = isPublic;
this.isOperational = true; // This is required since bluebird 4 doesn't append it anymore.
Error.captureStackTrace(this, this.constructor.name);
}
}
/**
* Class representing an API error.
* @extends ExtendableError
*/
class APIError extends ExtendableError {
/**
* Creates an API error.
* @param {string} message - Error message.
* @param {number} status - HTTP status code of error.
* @param {boolean} isPublic - Whether the message should be visible to user or not.
*/
constructor(message, status = httpStatus.INTERNAL_SERVER_ERROR, isPublic = false) {
super(message, status, isPublic);
}
}
export default APIError;
如何在测试中测试Promise.reject?
describe('# POST /api/v1/auth/login', () => {
it('should return Authentication error', () => {
return request(app)
.post('/api/v1/auth/login')
.send(invalidUserCredentials)
// following lines are not valid anymore with Promise.reject ..
.expect(httpStatus.UNAUTHORIZED)
.then((res) => {
expect(res.body.message).to.equal('Authentication error');
});
});
答案 0 :(得分:0)
您根本没有处理错误/拒绝。您需要发送错误返回。我建议在快递路由的末尾添加错误处理中间件,然后使用next(err)
传递给它。
// at the end of your routes
app.use(function(err, req, res, next) {
// do whatever you want, but at least send status and message:
res.status(err.status).json({
message: err.message,
});
});
现在通过以下方式处理路线中的错误:
.catch(() => {
const err = new APIError('Authentication error', httpStatus.UNAUTHORIZED, true);
return next(err);
});
答案 1 :(得分:0)
现在运行正常,我的express.js错误处理有问题..因为APIError类型检查总是假的...扩展es6-error包而不是Error解决这个Babel问题... < / p>
<强> APIError.js 强>
(3) sauce = urllib.request.urlopen(url, auth=(username, password)).read() (3)
instead of (1)
<强> Express.js 强>
import ExtendableError from 'es6-error'; // solve Babel issue w isInstanceOf()
import httpStatus from 'http-status'
class MyExtendableError extends ExtendableError {
constructor(message, status, isPublic) {
super(message);
this.name = this.constructor.name;
this.message = message;
this.status = status;
this.isPublic = isPublic;
this.isOperational = true; // This is required since bluebird 4 doesn't append it anymore.
Error.captureStackTrace(this, this.constructor.name);
}
}
/**
* Class representing an API error.
* @extends MyExtendableError
*/
class APIError extends MyExtendableError {
constructor(message, status = httpStatus.INTERNAL_SERVER_ERROR, isPublic = false) {
super(message, status, isPublic);
}
}
export default APIError;
<强> auth.route.js 强>
// catch 404 and forward to error handler
/* istanbul ignore next */
app.use((req, res, next) => {
const err = new APIError('API not found', httpStatus.NOT_FOUND);
return next(err);
});
// if error is not an instance Of APIError, convert it.
app.use((err, req, res, next) => {
if (err instanceof expressValidation.ValidationError) {
// validation error contains errors which is an array of error each containing message[]
const unifiedErrorMessage = err.errors.map((error) => {
return error.messages.join('. ');
}).join(' and ');
const error = new APIError(unifiedErrorMessage, err.status, true);
res.status(error.status).json({
message: err.isPublic ? err.message : httpStatus[err.status],
stack: (config.env === 'test' || config.env === 'development' ) ? err.stack : {}
});
} else if (!(err instanceof APIError)) {
const apiError = new APIError(err.message, err.status, err.isPublic);
res.status(apiError.status).json({
message: err.isPublic ? err.message : httpStatus[err.status],
stack: (config.env === 'test' || config.env === 'development' ) ? err.stack : {}
});
}else {
res.status(err.status).json({
message: err.isPublic ? err.message : httpStatus[err.status],
stack: (config.env === 'test' || config.env === 'development' ) ? err.stack : {}
});
}
});
<强> auth.controller.js 强>
import express from 'express';
import validate from 'express-validation';
import expressJwt from 'express-jwt';
import paramValidation from '../../../config/param-validation';
import authCtrl from '../controllers/auth.controller';
import config from '../../../config/config';
const router = express.Router();
/** POST /api/auth/login - Returns token if correct username and password is provided */
router.route('/login')
.post(validate(paramValidation.login), authCtrl.login);
<强> auth.test.js 强>
function login(req, res, next) {
// fetch user from the db
User.findOne(req.body)
.exec() // make query a Promise
.then((user) => {
const token = jwt.sign({ username: user.username }, config.jwtSecret);
return res.json({ token, username: user.username });
})
.catch(() => {
const err = new APIError('Authentication error', httpStatus.UNAUTHORIZED, true);
return next(err);
});
}