Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throwing HealthCheckError in synchronous HealthIndicatorFunction does not work properly #2083

Closed
2 of 4 tasks
andreialecu opened this issue Nov 23, 2022 · 5 comments · Fixed by #2084
Closed
2 of 4 tasks

Comments

@andreialecu
Copy link
Contributor

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

There is an issue with non-async health indicator functions due to the following:

const result = await Promise.allSettled(healthIndicators.map((h) => h()));

If an error is thrown synchronously, then the health check will reply with {"statusCode":500,"message":"Internal server error"} and the server will log the error.

Minimum reproduction code

@Get()
  @HealthCheck()
  async check() {
    const result = await this.health.check([
      () => throw new HealthCheckError('error', {}), // if changed to `async () => `, it works
    ])
  }

Steps to reproduce

No response

Expected behavior

It should not depend on the function being async.

Package version

9.1.3

NestJS version

not relevant

Node.js version

not relevant

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

@andreialecu
Copy link
Contributor Author

Fixed in #2084 (/cc @BrunnerLivio)

@BrunnerLivio
Copy link
Member

@andreialecu Curious; why would you want to run a synchronous health check?

@andreialecu
Copy link
Contributor Author

andreialecu commented Nov 24, 2022

Because I have a specific case where I have a stream that sometimes randomly stops working, so I store a lastMessageReceived timestamp and check if nothing got in in the past 2 minutes, then fail the health check because of it.

I had to dig through the Terminus code to see why this wasn't working right.

If non async healthchecks should not be supported, the types could prevent a non-promise from being passed. But they specifically allow it:

export type HealthIndicatorFunction = () =>
| PromiseLike<HealthIndicatorResult>
| HealthIndicatorResult;

So this seemed like a bug to me.

PS: I'm currently working around it by passing an async function, but I thought someone else might run into this in the future, and it was worth fixing.

@BrunnerLivio
Copy link
Member

@andreialecu Alright makes sense to me! Let's go forward with your PR then :)

@BrunnerLivio
Copy link
Member

Released with 9.1.4 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants