Sfoglia il codice sorgente

fix(core): Fix error when using HttpHealthCheckStrategy

Fixes #2617
Michael Bromley 2 anni fa
parent
commit
9ab2e4df70

+ 2 - 2
packages/core/src/health-check/health-check-registry.service.ts

@@ -15,8 +15,8 @@ import { HealthIndicatorFunction } from '@nestjs/terminus';
  * service to add a check for that dependency to the Vendure health check.
  *
  *
- * Since v1.6.0, the preferred way to implement a custom health check is by creating a new
- * {@link HealthCheckStrategy} and then passing it to the `systemOptions.healthChecks` array.
+ * Since v1.6.0, the preferred way to implement a custom health check is by creating a new {@link HealthCheckStrategy}
+ * and then passing it to the `systemOptions.healthChecks` array.
  * See the {@link HealthCheckStrategy} docs for an example configuration.
  *
  * The alternative way to register a health check is by injecting this service directly into your

+ 2 - 1
packages/core/src/health-check/health-check.module.ts

@@ -8,11 +8,12 @@ import { JobQueueModule } from '../job-queue/job-queue.module';
 
 import { HealthCheckRegistryService } from './health-check-registry.service';
 import { HealthController } from './health-check.controller';
+import { CustomHttpHealthIndicator } from './http-health-check-strategy';
 
 @Module({
     imports: [TerminusModule, ConfigModule, JobQueueModule],
     controllers: [HealthController],
-    providers: [HealthCheckRegistryService],
+    providers: [HealthCheckRegistryService, CustomHttpHealthIndicator],
     exports: [HealthCheckRegistryService],
 })
 export class HealthCheckModule {

+ 49 - 6
packages/core/src/health-check/http-health-check-strategy.ts

@@ -1,10 +1,11 @@
-import { HealthIndicatorFunction, HttpHealthIndicator } from '@nestjs/terminus';
+import { Injectable, Scope } from '@nestjs/common';
+import { HealthCheckError, HealthIndicatorFunction, HealthIndicatorResult } from '@nestjs/terminus';
+import { HealthIndicator } from '@nestjs/terminus/dist/health-indicator/index';
+import fetch from 'node-fetch';
 
 import { Injector } from '../common/index';
 import { HealthCheckStrategy } from '../config/system/health-check-strategy';
 
-let indicator: HttpHealthIndicator;
-
 export interface HttpHealthCheckOptions {
     key: string;
     url: string;
@@ -35,13 +36,55 @@ export interface HttpHealthCheckOptions {
  */
 export class HttpHealthCheckStrategy implements HealthCheckStrategy {
     constructor(private options: HttpHealthCheckOptions) {}
+    private injector: Injector;
 
-    async init(injector: Injector) {
-        indicator = await injector.get(HttpHealthIndicator);
+    init(injector: Injector) {
+        this.injector = injector;
     }
 
     getHealthIndicator(): HealthIndicatorFunction {
         const { key, url, timeout } = this.options;
-        return () => indicator.pingCheck(key, url, { timeout });
+        return async () => {
+            const indicator = await this.injector.resolve(CustomHttpHealthIndicator);
+            return indicator.pingCheck(key, url, timeout);
+        };
+    }
+}
+
+/**
+ * A much simplified version of the Terminus Modules' `HttpHealthIndicator` which has no
+ * dependency on the @nestjs/axios package.
+ */
+@Injectable({
+    scope: Scope.TRANSIENT,
+})
+export class CustomHttpHealthIndicator extends HealthIndicator {
+    /**
+     * Prepares and throw a HealthCheckError
+     *
+     * @throws {HealthCheckError}
+     */
+    private generateHttpError(key: string, error: any) {
+        const response: { [key: string]: any } = {
+            message: error.message,
+        };
+        if (error.response) {
+            response.statusCode = error.response.status;
+            response.statusText = error.response.statusText;
+        }
+        throw new HealthCheckError(error.message, this.getStatus(key, false, response));
+    }
+
+    async pingCheck(key: string, url: string, timeout?: number): Promise<HealthIndicatorResult> {
+        let isHealthy = false;
+
+        try {
+            await fetch(url, { timeout });
+            isHealthy = true;
+        } catch (err) {
+            this.generateHttpError(key, err);
+        }
+
+        return this.getStatus(key, isHealthy);
     }
 }