google-cloud-node icon indicating copy to clipboard operation
google-cloud-node copied to clipboard

Unhandled promise rejections in Secrets Manager

Open ssundarraj opened this issue 2 years ago • 5 comments

Thanks for stopping by to let us know something could be better!

PLEASE READ: If you have a support contract with Google, please create an issue in the support console instead of filing on GitHub. This will ensure a timely response.

Please run down the following list and make sure you've tried the usual "quick fixes":

  • Search the issues already opened: https://github.com/GoogleCloudPlatform/google-cloud-node/issues
  • Search StackOverflow: http://stackoverflow.com/questions/tagged/google-cloud-platform+node.js
  • Check our Troubleshooting guide: https://googlecloudplatform.github.io/google-cloud-node/#/docs/guides/troubleshooting
  • Check our FAQ: https://googlecloudplatform.github.io/google-cloud-node/#/docs/guides/faq

If you are still having issues, please be sure to include as much information as possible:

Environment details

  • which product (packages/*): google-cloud-secretmanager
  • OS: MacOS
  • Node.js version: v18.17.0
  • npm version: 9.6.7
  • google-cloud-node version: ^5.0.1

Steps to reproduce

Please include any and all code and/or steps related to reproducing the bug.

  1. revoke ADC permissions
  2. call listSecrets in a try..catch
  3. initialize is called under the hood (here) but not awaited which leads to an unhandled promise rejection

Making sure to follow these steps will guarantee the quickest resolution possible.

Thanks!

Note: I'm happy to put up a fix for this. Seems like the code is generated. Where is the template from which it is generated?

ssundarraj avatar Oct 18 '23 18:10 ssundarraj

If my understanding of your issue is correct, there is no problem. It seems related to the following rejection conditions.

https://github.com/googleapis/google-cloud-node/blob/4ae169c9d2fc365e1d2b484f58fceaa88af95764/packages/google-cloud-secretmanager/src/v1/secret_manager_service_client.ts#L287:L288

As I understand it, the SecretManagerClient flow can be briefly described as follows.

SecretManagerClient -> initialize()-> listSecrets() -> close() -> if (stub && !this._terminated) -> this._terminated = true -> async retry -> initialize() -> if (this._terminated) -> reject

k-oguma avatar Oct 19 '23 16:10 k-oguma

Hi @ssundarraj, would you mind posting the behavior you're getting vs. expected behavior? I also think understanding your use case a bit better would help. Thanks!

sofisl avatar Oct 19 '23 20:10 sofisl

Thanks for the response @k-oguma and @sofisl

In listSecrets (source) I see this code:

    // ...
    this.initialize();
    return this.innerApiCalls.listSecrets(request, options, callback);

I'm expecting this:

    // ...
    await this.initialize();  // <--------------------------------------------- add await here
    return this.innerApiCalls.listSecrets(request, options, callback);

Here's why I think the client should await the call to initialize: In my code that uses the client, I do the following:

try {
  await client.initialize()
  // something could happen here (see below)
  const [output] = await client.listSecrets(...)
} catch (e) { 
  // handle error
}

However, something could change between my call to initialize and my call to listSecrets in a way that the internal call to initialize from listSecrets fails (eg: revoking credentials). This will cause an unhandled promise rejection because the call to initialize is not awaited and there is no way to catch this in my code.

ssundarraj avatar Oct 19 '23 20:10 ssundarraj

hey @sofisl any timeline for this?

ssundarraj avatar Nov 21 '23 23:11 ssundarraj

I'll take a look next week!

sofisl avatar Nov 22 '23 16:11 sofisl