0

I am having a very hard time trying to solve a few functions that work perfectly fine on my laptop development environment (even if I run it with NODE_ENV=production) but when I deploy it to Google Cloud Run I get errors such as

Default
2021-12-15T12:16:35.016406Z at TCP.done (_tls_wrap.js:564:7)
Default
2021-12-15T12:16:35.016414Z(Use `node --trace-warnings ...` to show where the warning was created)
Default
2021-12-15T12:16:35.016426Z(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
Default
2021-12-15T12:16:35.116284Z(node:1) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Default
2021-12-15T12:16:35.116931Z(node:1) UnhandledPromiseRejectionWarning: Error: socket hang up
Default
2021-12-15T12:16:35.116954Z at connResetException (internal/errors.js:639:14)
Default
2021-12-15T12:16:35.116969Z at TLSSocket.socketCloseListener (_http_client.js:449:25)
Default
2021-12-15T12:16:35.116979Z at TLSSocket.emit (events.js:412:35)
Default
2021-12-15T12:16:35.116989Z at net.js:686:12
Default
2021-12-15T12:16:35.116999Z at TCP.done (_tls_wrap.js:564:7)

causing my script to halt. In my local version it continues without stopping. It is very frustrating as I need to upload the code to Cloud Run all the time in order to test my code. I am testing it blindly as the errors do not appear in my development version.

I am quite new to Node.js and are constantly having a hard time with .then(), chaining .then(), promises, using resolve() so the code is likely to be wrong.

My questions here:

  1. Why is this error only appearing on Cloud Run?
  2. How can I configure my local computer the same way so it shows the same warnings and errors - so I can troubleshoot this?

My code (simplified):

function createOrUpdateSpotterData(data) {

   // NOTE: Data comes from API and not from DB, thus no info such as twitter_status
   // TODO: Separate into a create or update, in order to not check twitter ID every time.
   return new Promise( async function (resolve) { 
      var twitterId = await twitterApi.getTwitterIdFromUsername(cleanedUsername)
      data['twitter_numeric'] = twitterId    
      resolve(data)

   }).then( (data) => {
      db.collection('spotters').doc(data.marker).set(data) 
   }).catch( (error) => { console.log(error) })
}

async function updateSpottersJsonToDb() {
   console.log("> updateSpottersJsonToDb")
   return new Promise( (resolve, reject) => {
      readStorageData(remote_files['spotters'])
         .then( async (spotterListJson) => {
            var spotterList = JSON.parse(spotterListJson)       
            await spotterList.forEach((spotter) => {
               createOrUpdateSpotterData(spotter)
            })                         
         })
         .then(() => { 
            resolve() 
         })
         .catch((error) => {console.error(error)})
   }).catch((error) => {console.error(error)})
Christoffer
  • 2,271
  • 3
  • 26
  • 57
  • 1
    For starters, you can stop using the promise anti-pattern of wrapping an existing promise in another manually created promise. It is very easy to make mistakes in error handling when you do that and it is entirely unnecessary. You can just use the first promise that the code is already generating - no need to wrap it in a new one. – jfriend00 Dec 15 '21 at 16:13
  • 1
    Is `createOrUpdateSpotterData()` asynchronous? FYI, the `await` in `await spotterList.forEach(...)` does NOTHING because `.forEach()` has no return value and is not `async` aware. `await` only does something when you are awaiting a promise. If this loop has asynchronous stuff in it, change it to a plain `for` loop and `await` the actual asynchronous operation inside the loop. – jfriend00 Dec 15 '21 at 16:17
  • 1
    Also, are you aware that `.catch((error) => {console.error(error)})` will log the error and then "eat" it so that the caller never sees the error? – jfriend00 Dec 15 '21 at 16:19
  • Thanks for your comments. I am aware that I am likely doing a lot of really bad mistakes as I am learning while coding. I find it difficult, however, to get a good intuition about promise, .then and await. 1. What do you mean, specifically, by promise anti-pattern. Do you mean having .then() inside the new Promise? – Christoffer Dec 15 '21 at 22:47
  • 2. createOrUpdateSpotterData() is not asynchronous. Would it change anything if it was? Thanks for the headsup about await and forEach, I have got that feeling but have not been able to confirm that. – Christoffer Dec 15 '21 at 22:48
  • 3. I was not aware about that with .catch but not entirely understand what you mean. How should it look in order for me to display the error in the log then? I thought this was the right way. – Christoffer Dec 15 '21 at 22:52
  • I would need to see the code for these functions you're calling to understand what is an isn't asynchronous and know better how this should be written. – jfriend00 Dec 15 '21 at 23:54
  • As this is actually a matter of two different (albeit related) questions, I created a new Question here: https://stackoverflow.com/questions/70371992/how-can-i-am-make-sure-these-chain-of-functions-in-node-js-are-performed-in-orde . I would be very glad if you gave me your thoughts there! – Christoffer Dec 16 '21 at 00:39
  • Also, note that your errors are TLS related, so: are you actually testing https, rather than plain http, locally? If not, you may want to sort out a way to do proper https localhost testing (e.g. using [mkcert](https://github.com/FiloSottile/mkcert) and providing Node with key/cert `pem` files for `localhost`). – Mike 'Pomax' Kamermans Dec 16 '21 at 00:48
  • Ah! I did not think about that! No, I am not testing https locally. That might be the reason my results differ. I don't understand really why it would cause these issues but at least I can possibly get the same errors locally. I think this comment is worthy of being an answer. – Christoffer Dec 16 '21 at 07:47

1 Answers1

0

It is quite embarrasing to admit but I was a bit overwhelmed by the quantity of this 'error message' that I could not see the forest for the trees. It was after all just a warning and by filtering the logs (on Google Cloud Logs) on std.out I realized this was not causing any of the issues I was having in my application.

The cause of this issue however was that I was not catching errors in my Promises correctly, which is really another issue (being discussed here).

If you find this through Google later on, it could be good to know that you can surpress this warning with process.on().

Christoffer
  • 2,271
  • 3
  • 26
  • 57