2

I ran into some issues with my program, so I started to learn how to use the node.js debugger. I have the following index.js:

import app from "./server.js"   // imports root
import mongodb from "mongodb"   // helps conect to mongodb
import dotenv from "dotenv"     // helps configure environment variables automatically
import DailyDAO from "./dao/dailyDAO.js"    // DAO file contains CRUD material

// configures dotenv
dotenv.config()       // New breakpoint here
const MongoClient = mongodb.MongoClient 

// This is the port where our local server will listen to the MongoDB Atlas server
const port = process.env.PORT || 8000
const url = process.env.SOLAR_DB_URI    

// Connects local VSC server to the MongoDB Atlas server
MongoClient.connect(
    url,
    {
        maxPoolSize: 50,
        waitQueueTimeoutMS: 2500
    }
)
.catch(err => { // If there is an error, this is executed
    console.error(err.stack)
    process.exit(1)
})
.then(async client => { 
    await DailyDAO.injectDB(client)
    app.listen(port, () => {
        console.log('Connected to: ' + url)
        console.log('listening on port: ' + port)
    })
})

When running this through the debugger with no breakpoints, I receive the error:

TypeError: Cannot read properties of undefined (reading 'startsWith')

When I stop at the breakpoint, I can see that port and url are both undefined. When I run the program normally, both variables have the expected values.

These variables are defined in a separate file .env. So I'm assuming that when running this file through the debugger, it is not accessing .env properly. Why does the debugger do this, and how do I make index.js access the values in .env while in the debugger?

Edit: This is what my .env file looks like

SOLAR_DB_URI=mongodb+srv://admin:fakepassword@solarpanel-db.sbqf66p.mongodb.net/daily_production?retryWrites=true&w=majority
PORT=5000
SOLAR_NS=daily_production

Edit: I am using a node.js debugger that comes built into VSC. To start the debugger, I select the desired file and select the run and e (in this case index.js) from my explorer and then select the "Run and Debug" button.

Edit: Ok so I made a different breakpoint at dotenv.config(). It turns out that this function is incorrectly resolving the path of my cwd.

Edit: Alright so, inside dotenv.config() looks like this:

function config(options) {
  // Irrelevant code  

  let dotenvPath = path.resolve(process.cwd(), '.env');  // There is a problem here

  // Irrelevant code
}

The directory where index.js and .env are located is %PATH%\solarmonitor\backend\, but when I run the debugger it's resolving to just %PATH%\solarmonitor\ instead.

Edit: These are my debugger's configurations from launch.json, as requested by @Bergi:

{
    /?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "skipFiles": [
                "<node_internals>/**"
            ],
            "program": "${workspaceFolder}\\backend\\index.js"
        }
    ]
}
Juan David
  • 49
  • 5
  • 1
    What debugger are you using and how are you starting it? And how exactly are the environment variables `PORT` and `SOLAR_DB_URI` getting configured. Presumably, they are just not configured in the environment that you're using when you run the debugger. – jfriend00 Oct 07 '22 at 23:25
  • Dotenv is path-dependent iirc. So make sure your debugger starts the `node` process in the same working directory as your normal execution. – Bergi Oct 07 '22 at 23:31
  • @Bergi `node` starts in the same directory as the selected file. The `index.js` and `.env` are in the same directory, so they should be able to interact normally no? – Juan David Oct 08 '22 at 00:41
  • @jfriend00 I have just added that information as an edit. – Juan David Oct 08 '22 at 00:47
  • "*`node` starts in the same directory as the selected file*" - are you sure there? Could you post your *launch.json* (at least the part with the debugging configuration), please? – Bergi Oct 08 '22 at 01:51
  • @Bergi just posted it. The program launches from `\backend\index.js` which is the expected directory. Also, I think that the `dotenv.config()` might be the problem. Inside the function, the path to the cwd is resolving incorrectly. I added some edits with that info. – Juan David Oct 08 '22 at 03:09

1 Answers1

1

You basically figured out what the problem is already - your program is started with in wrong working directory. VS Code is basically running node backend\index.js in your workspace folder, which is the default working directory for any launch configuration.

You can change this setting using the cwd launch configuration attribute:

{
    "type": "node",
    "request": "launch",
    "name": "Launch Program",
    "skipFiles": [
        "<node_internals>/**"
    ],
    "cwd": "${workspaceFolder}\\backend",
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    "program": "${workspaceFolder}\\backend\\index.js"
}

For your particular problem, you could also configure VS Code to provide the environment variables from your .env file, in which case you wouldn't need dotenv.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Alright! Now I can debug in peace. But you know, I'm still confused. If the debugger knows the absolute path of the program already, as shown in the `program` attribute, why do I need to specify the `cwd`? – Juan David Oct 08 '22 at 04:42
  • NEVERMIND! I just read the documentation for `cwd`. It always defaults to the "workingFolder` unless otherwise specified. I'm good. I wish I could up-vote, but I don't have enough reputation yet. – Juan David Oct 08 '22 at 04:44