My deployment on Heroku keep crashing on the POST request when I send the mulitpart form. I can't see in the logs if it's on the upload (multer) function, save (mongoose) function or sendMail (nodemailer) function. The only thing I see in the logs is a H18 error: Internal Server.
Router.js
const express = require("express");
const mongoose = require("mongoose");
const router = express.Router();
const multer = require("multer");
const path = require("path");
const File = require("../models/Files");
const mail = require("../handlers/mailer");
// Set storage engine
const storage = multer.memoryStorage();
// Init upload
const upload = multer({
storage: storage
}).single("file");
router.get("/", (req, res) => {
res.render("index");
});
router.post("/send", async (req, res, next) => {
await upload(req, res, async err => {
if (err) {
console.log("error by uploading file:", err);
} else {
console.log(`File is uploaded to the memoryStorage: ${req.file.originalname} `);
}
// Create a model to save in the database
const fileUpload = new File({
fromEmail: "<dk@bigbrother.nl>",
fromName: '"Dennis Klarenbeek
Catch all uncaught exceptions in nodejs to get a better idea where things break.
Add this lines into your nodejs file
I have realized that this error most times comes when one is trying to upload a large file, though heroku said "There is not a limit on filesize for uploads", your app probably got a large file that exceed the Heroku time bond for all requests on the Heroku platform must return the first byte within 30 seconds, it then resulted to the closing of the backend socket, belonging to your app’s web process before the backend returned an HTTP response.
But Heroku gave more reason why you might end up with that error, which I will advice you read for more clarification H18 - Server Request Interrupted
Resolution
The heroku H18 error is thrown when the socket was destroyed before a response is completed. From heroku docs it states:
There are some steps we can do to refactor the code so we use multer as a middleware and to improve the error handling so we can see where the error actually occurs.
To catch errors thrown when resolving an await, you need to wrap it around a
try...catch
block. It works exactly like the Promise.catch.