Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

While using multer, erros crash server #228

Open
AlanGreyjoy opened this issue Dec 1, 2022 · 1 comment
Open

While using multer, erros crash server #228

AlanGreyjoy opened this issue Dec 1, 2022 · 1 comment

Comments

@AlanGreyjoy
Copy link

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...
@bhattiasad99
Copy link

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 };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants