node-express-boilerplate
node-express-boilerplate copied to clipboard
While using multer, erros crash server
I have noticed that when using multer, the server crashes when you throw new ApiError()
and I am pulling my hair out trying to track it down.
Route
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'src/data/mmsTemp/');
},
filename: (req, file, cb) => {
cb(null, Date.now() + '-' + file.originalname);
},
});
const upload = multer({ storage });
router
.route('/:api_key/messages/mms')
.get(apiKey, controllers.messages.getMMSMessages)
.post(
apiKey,
upload.single('file'),
controllers.messages.sendMMS
);
Controller
module.exports.sendMMS = async (req, res) => {
if (!req.file) {
throw new ApiError(httpStatus.BAD_REQUEST, 'Missing file')
}
const data = {
...req.body,
file: req.file,
apiKey: req.user.apiKey,
apiSecret: req.user.apiSecret,
domain: req.user.domain,
};
await cpaasService.messages.sendMMS(data)
return shSuccess(res);
};
Stack
error: Error: Missing file
at module.exports.sendMMS (C:\XXXXXXXX\src\controller\ucaas\messages.controller.js:44:11)
at Layer.handle [as handle_request] (C:\XXXXXXXX\node_modules\express\lib\router\layer.js:95:5)
at next (C:\XXXXXXXX\node_modules\express\lib\router\route.js:144:13)
at done (C:\XXXXXXXX\node_modules\multer\lib\make-middleware.js:45:7)
at indicateDone (C:\XXXXXXXX\node_modules\multer\lib\make-middleware.js:49:68)
at Multipart.<anonymous> (C:\XXXXXXXX\node_modules\multer\lib\make-middleware.js:166:7)
at Multipart.emit (node:events:527:28)
at Multipart.emit (node:domain:475:12)
at emitCloseNT (node:internal/streams/destroy:138:10)
at processTicksAndRejections (node:internal/process/task_queues:82:21)
info: Server closed
[nodemon] app crashed - waiting for file changes before starting...
I also used multer in my application, faced several problems but now its working fine for me, ill let you know how i used it.
import { Router } from "express";
import { auth } from "../middlewares/index.js";
import { addPlan } from "../controllers/training-plan/index.js";
import multer from "multer";
import { failure } from "../../utils/helpers/responses.js";
import { getDirName } from "../../utils/helpers/dirname.js";
import uniqid from "uniqid";
import { UNKNOWN_SERVER_ERROR } from "../../config/index.js";
import { getLastElementOfArray } from "./../../utils/helpers/utility-functions.js";
import path from "path";
var storage = multer.diskStorage({
destination: function (req, file, cb) {
try {
cb(null, getDirName(import.meta.url)?.__dirname + "/");
} catch (err) {
return res.status(UNKNOWN_SERVER_ERROR).json({
message: err.message,
errorInstance: { ...err },
});
}
},
filename: function (req, file, cb) {
try {
// cb(null, Date.now() + uniqid() + path.extname(file.originalname));
cb(
null,
"Answer" +
"." +
getLastElementOfArray(file.mimetype.split("/")[1].split("."))
);
} catch (err) {
return res.status(UNKNOWN_SERVER_ERROR).json({
message: err.message,
errorInstance: { ...err },
});
}
// cb(null, "Answer" + "." + file.mimetype.split("/")[1]);
},
});
const upload = multer({ storage: storage });
const router = Router();
// Post Request
router.post("/add-plan", auth, upload.single("file"), addPlan);
export default router;
This is how my API looked like:
export default async (req, res) => {
let CONSECUTIVE_EMPTY_VALUES = 10;
try {
let results = [];
const workbook = xlsx.readFile(
`${getDirName(import.meta.url)?.__dirname}/../../routes/${
req.file.filename
}`
);
const sheet = workbook.Sheets[workbook.SheetNames[0]];
// Get column range from the sheet
const range = xlsx.utils.decode_range(sheet["!ref"]);
for (let c = range.s.c; c <= range.e.c; c++) {
let column = [];
let emptyCellsCount = 0; // Initialize empty cell count for current column
for (let r = range.s.r; r <= range.e.r; r++) {
let cell = sheet[xlsx.utils.encode_cell({ r: r, c: c })];
let value = cell ? cell.v : "";
if (value === "") {
// If cell is empty, increment empty cell count
emptyCellsCount++;
if (emptyCellsCount > CONSECUTIVE_EMPTY_VALUES) {
// If CONSECUTIVE_EMPTY_VALUES found, move to next column
break;
}
} else {
// If cell is not empty, reset empty cell count
emptyCellsCount = 0;
}
column.push(value);
}
results.push(column);
}
return await handleCsvData(req, res, results);
} catch (err) {
return failure(req, res, UNKNOWN_SERVER_ERROR, "00008", err.message, {
error: { ...err },
});
}
};
getDirName function:
import path from "path";
import { fileURLToPath } from "url";
const getDirName = (filepath) => {
const __filename = fileURLToPath(filepath);
const __dirname = path.dirname(__filename);
return {
__filename,
__dirname,
};
};
export { getDirName };