monkeytype/backend/middlewares/api-utils.js

56 lines
1.6 KiB
JavaScript
Raw Normal View History

const joi = require("joi");
const MonkeyError = require("../handlers/error");
/**
* This utility serves as an alternative to wrapping express handlers with try/catch statements.
* Any routes that use an async handler function should wrap the handler with this function.
* Without this, any errors thrown will not be caught by the error handling middleware, and
* the app will hang!
*/
function asyncHandlerWrapper(handler) {
return async (req, res, next) => {
try {
const handlerData = await handler(req, res);
if (!res.headersSent && handlerData) {
res.json(handlerData);
}
next();
} catch (error) {
next(error);
}
};
}
function requestValidation(validationSchema) {
return (req, res, next) => {
/**
* In dev environments, as an alternative to token authentication,
* you can pass the authentication middleware by having a user id in the body.
* Inject the user id into the schema so that validation will not fail.
*/
if (process.env.MODE === "dev") {
validationSchema.body = {
uid: joi.any(),
...(validationSchema.body ?? {}),
};
}
Object.keys(validationSchema).forEach((key) => {
const schema = validationSchema[key];
const joiSchema = joi.object().keys(schema);
const { error } = joiSchema.validate(req[key] ?? {});
if (error) {
const errorMessage = error.details[0].message;
throw new MonkeyError(400, `Invalid request: ${errorMessage}`);
}
});
next();
};
}
module.exports = {
asyncHandlerWrapper,
requestValidation,
};