mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 07:07:35 +01:00
handle mongoose validation errors, fix bug in import and add more tests for errors
This commit is contained in:
@@ -82,6 +82,65 @@ describe('errorHandler', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handle http-errors errors', () => {
|
||||||
|
let error = new Error('custom message');
|
||||||
|
error.statusCode = 422;
|
||||||
|
|
||||||
|
errorHandler(error, req, res, next);
|
||||||
|
|
||||||
|
expect(res.status).to.be.calledOnce;
|
||||||
|
expect(res.json).to.be.calledOnce;
|
||||||
|
|
||||||
|
expect(res.status).to.be.calledWith(error.statusCode);
|
||||||
|
expect(res.json).to.be.calledWith({
|
||||||
|
error: error.name,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handle express-validator errors', () => {
|
||||||
|
let error = [{param: 'param', msg: 'invalid param'}];
|
||||||
|
|
||||||
|
errorHandler(error, req, res, next);
|
||||||
|
|
||||||
|
expect(res.status).to.be.calledOnce;
|
||||||
|
expect(res.json).to.be.calledOnce;
|
||||||
|
|
||||||
|
expect(res.status).to.be.calledWith(400);
|
||||||
|
expect(res.json).to.be.calledWith({
|
||||||
|
error: 'BadRequest',
|
||||||
|
message: 'Invalid request parameters.',
|
||||||
|
errors: error,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handle Mongoose Validation errors', () => {
|
||||||
|
let error = new Error('User validation failed.');
|
||||||
|
error.name = 'ValidationError';
|
||||||
|
|
||||||
|
error.errors = {
|
||||||
|
'auth.local.email': {
|
||||||
|
path: 'auth.local.email',
|
||||||
|
message: 'Invalid email.',
|
||||||
|
value: 'not an email',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
errorHandler(error, req, res, next);
|
||||||
|
|
||||||
|
expect(res.status).to.be.calledOnce;
|
||||||
|
expect(res.json).to.be.calledOnce;
|
||||||
|
|
||||||
|
expect(res.status).to.be.calledWith(400);
|
||||||
|
expect(res.json).to.be.calledWith({
|
||||||
|
error: 'BadRequest',
|
||||||
|
message: 'User validation failed.',
|
||||||
|
errors: [
|
||||||
|
{path: 'auth.local.email', message: 'Invalid email.', value: 'not an email'}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('logs error', () => {
|
it('logs error', () => {
|
||||||
let error = new BadRequest();
|
let error = new BadRequest();
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { authWithHeaders } from '../../middlewares/api-v3/auth';
|
|||||||
import {
|
import {
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../../libs/api-v3/errors';
|
} from '../../libs/api-v3/errors';
|
||||||
import passwordUtils from '../../libs/api-v3/password';
|
import * as passwordUtils from '../../libs/api-v3/password';
|
||||||
import { model as User } from '../../models/user';
|
import { model as User } from '../../models/user';
|
||||||
import EmailUnsubscription from '../../models/emailUnsubscription';
|
import EmailUnsubscription from '../../models/emailUnsubscription';
|
||||||
import { sendTxn as sendTxnEmail } from '../../libs/api-v3/email';
|
import { sendTxn as sendTxnEmail } from '../../libs/api-v3/email';
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
BadRequest,
|
BadRequest,
|
||||||
InternalServerError,
|
InternalServerError,
|
||||||
} from '../../libs/api-v3/errors';
|
} from '../../libs/api-v3/errors';
|
||||||
|
import { map } from 'lodash';
|
||||||
|
|
||||||
export default function errorHandler (err, req, res, next) {
|
export default function errorHandler (err, req, res, next) {
|
||||||
if (!err) return next();
|
if (!err) return next();
|
||||||
@@ -36,7 +37,19 @@ export default function errorHandler (err, req, res, next) {
|
|||||||
// Handle errors by express-validator
|
// Handle errors by express-validator
|
||||||
if (Array.isArray(err) && err[0].param && err[0].msg) {
|
if (Array.isArray(err) && err[0].param && err[0].msg) {
|
||||||
responseErr = new BadRequest('Invalid request parameters.');
|
responseErr = new BadRequest('Invalid request parameters.');
|
||||||
responseErr.errors = err;
|
responseErr.errors = err; // TODO format
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle mongoose validation errors
|
||||||
|
if (err.name === 'ValidationError') {
|
||||||
|
responseErr = new BadRequest(err.message);
|
||||||
|
responseErr.errors = map(err.errors, (mongooseErr) => {
|
||||||
|
return {
|
||||||
|
path: mongooseErr.path,
|
||||||
|
message: mongooseErr.message,
|
||||||
|
value: mongooseErr.value,
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!responseErr || responseErr.httpCode >= 500) {
|
if (!responseErr || responseErr.httpCode >= 500) {
|
||||||
@@ -48,11 +61,14 @@ export default function errorHandler (err, req, res, next) {
|
|||||||
responseErr = new InternalServerError();
|
responseErr = new InternalServerError();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO unless status >= 500 return data attached to errors
|
let jsonRes = {
|
||||||
|
error: responseErr.name,
|
||||||
|
message: responseErr.message,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (responseErr.errors) jsonRes.errors = responseErr.errors;
|
||||||
|
|
||||||
return res
|
return res
|
||||||
.status(responseErr.httpCode)
|
.status(responseErr.httpCode)
|
||||||
.json({
|
.json(jsonRes);
|
||||||
error: responseErr.name,
|
|
||||||
message: responseErr.message,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user