Search code examples
node.jsheroku

Unable to deploy Contact Page Backend in Node.js to Heroku


I wrote backend in Node.js for the contact page on my portfoilio on Firebase. I'm trying to deploy it, but when open the app, it gives me an 'Application Error'. When I go to the logs, it gives me error code=H10 desc="App crashed".

Update: I also see an error Error: Cannot find module '@sendGrid/mail'.

I've tried a few things. I added "start": "node App.js" and "engines": { "node": "12.13.1" } to my package.json. I created a Procfile with web: node App.js. In my App.js, I changed my app.listen(4000, '0.0.0.0'); to app.listen(process.env.PORT || 4000);.

I'm not sure if I have to set process.env.PORT to something. How would I fix this?

Relevant Code

App.js

const express = require('express'); //Needed to launch server.
const bodyParser = require('body-parser');
const cors = require('cors'); //Needed to disable sendgrid security.
const sendGrid = require('@sendGrid/mail'); //Access SendGrid library to send emails.
sendGrid.setApiKey(process.env.SENDGRID_API_KEY);
const app = express(); //Alias from the express function.

app.use(bodyParser.json());

app.use(cors());

app.use((req, res, next) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
    next();
});

app.get('/api', (req, res, next) => {
    res.send('API Status: Running');
});

app.post('/api/email', (req, res, next) => {
    console.log(req.body);
    const msg = {
        to: '[email protected]',
        from: req.body.email,
        subject: req.body.subject,
        text: req.body.message
    }
    sendGrid.send(msg)
        .then(result => {
            res.status(200).json({
                success: true
            });
        })
        .catch(err => {
            console.log('error: ', err);
            res.status(401).json({
                success: false
            });
        });
});

app.listen(process.env.PORT || 4000);

Also, here's my package.json

{
  "name": "my-app-api",
  "version": "1.0.0",
  "description": "",
  "main": "App.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node App.js"
  },
  "author": "Daniel Zhang",
  "license": "ISC",
  "dependencies": {
    "@sendgrid/mail": "^7.2.2",
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "nodemon": "^2.0.4"
  },
  "engines": {
    "node": "12.13.1"
  },
  "devDependencies": {}
}

Also, here are the Application Logs:

2020-08-30T14:49:33.088197+00:00 heroku[web.1]: Starting process with command `node index.js`
2020-08-30T14:49:35.380821+00:00 heroku[web.1]: Process exited with status 1
2020-08-30T14:49:35.420886+00:00 heroku[web.1]: State changed from starting to crashed
2020-08-30T14:49:35.328408+00:00 app[web.1]: internal/modules/cjs/loader.js:800
2020-08-30T14:49:35.328435+00:00 app[web.1]:     throw err;
2020-08-30T14:49:35.328436+00:00 app[web.1]:     ^
2020-08-30T14:49:35.328436+00:00 app[web.1]: 
2020-08-30T14:49:35.328437+00:00 app[web.1]: Error: Cannot find module '@sendGrid/mail'
2020-08-30T14:49:35.328437+00:00 app[web.1]: Require stack:
2020-08-30T14:49:35.328437+00:00 app[web.1]: - /app/index.js
2020-08-30T14:49:35.328438+00:00 app[web.1]:     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:797:15)
2020-08-30T14:49:35.328438+00:00 app[web.1]:     at Function.Module._load (internal/modules/cjs/loader.js:690:27)
2020-08-30T14:49:35.328439+00:00 app[web.1]:     at Module.require (internal/modules/cjs/loader.js:852:19)
2020-08-30T14:49:35.328439+00:00 app[web.1]:     at require (internal/modules/cjs/helpers.js:74:18)
2020-08-30T14:49:35.328439+00:00 app[web.1]:     at Object.<anonymous> (/app/index.js:4:18)
2020-08-30T14:49:35.328440+00:00 app[web.1]:     at Module._compile (internal/modules/cjs/loader.js:959:30)
2020-08-30T14:49:35.328440+00:00 app[web.1]:     at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
2020-08-30T14:49:35.328440+00:00 app[web.1]:     at Module.load (internal/modules/cjs/loader.js:815:32)
2020-08-30T14:49:35.328441+00:00 app[web.1]:     at Function.Module._load (internal/modules/cjs/loader.js:727:14)
2020-08-30T14:49:35.328441+00:00 app[web.1]:     at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10) {
2020-08-30T14:49:35.328441+00:00 app[web.1]:   code: 'MODULE_NOT_FOUND',
2020-08-30T14:49:35.328442+00:00 app[web.1]:   requireStack: [ '/app/index.js' ]
2020-08-30T14:49:35.328442+00:00 app[web.1]: }
2020-08-30T14:49:46.278674+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/api" host=daniel-zhang-portfolio-backend.herokuapp.com request_id=b50170d2-6e1f-4697-aa35-3ea445d1d936 fwd="75.75.104.235" dyno= connect= service= status=503 bytes= protocol=https
2020-08-30T14:49:46.490432+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=daniel-zhang-portfolio-backend.herokuapp.com request_id=cb1bdef2-0cb6-400d-aaf5-e8e2c2b8fa35 fwd="75.75.104.235" dyno= connect= service= status=503 bytes= protocol=https

Also here's my file structure:

File Structure


Solution

  • In const sendGrid = require('@sendGrid/mail');, '@sendGrid/mail' should be '@sendgrid/mail'.