Skip to content

MikroOrmHealthIndicator does not work with the defineConfig helper #2259

@ctfdavis

Description

@ctfdavis

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

Summary of the issue

Currently, the pingDb method of the MikroOrmHealthIndicator class makes use of the type option of the MikroOrm configuration. However, the type would be undefined if the defineConfig helper exported from the driver package is used for the MikroOrm configuration without providing the type option, causing the pingDb method to fail with a rather cryptic error message:

undefined ping check is not implemented yet

In addition, the type option will be removed in MikroOrm v6, and the suggested way of defining configuration is using the defineConfig helper exported from the driver package.

The issue

Here’s the current implementation of pingDb method, which would throw a cryptic error message undefined ping check is not implemented yet if the user uses the defineConfig helper exported from the driver package to configure MikroOrm without providing the type option:

  private async pingDb(connection: MikroOrm.Connection, timeout: number) {
    let check: Promise<any>;
    const type = connection.getPlatform().getConfig().get('type’); // type can be undefined here!

    switch (type) {
      case 'postgresql':
      case 'mysql':
      case 'mariadb':
      case 'sqlite':
        check = connection.execute('SELECT 1');
        break;
      case 'mongo':
        check = connection.isConnected();
        break;
      default:
        throw new NotImplementedException(
          `${type} ping check is not implemented yet`, // if type is undefined, then we’d get a cryptic error message
        );
    }
    return await promiseTimeout(timeout, check);
  }

One way to fix it is to check the driver instead, which would work with both the original way of configuration and defineConfig helper:

  private async pingDb(connection: MikroOrm.Connection, timeout: number) {
    let check: Promise<any>;
    const driver = connection.getPlatform().getConfig().getDriver().constructor.name;

    switch (driver) {
      case 'PostgreSqlDriver':
      case 'MySqlDriver':
      case 'MariaDbDriver':
      case 'SqliteDriver':
        check = connection.execute('SELECT 1');
        break;
      case 'MongoDriver':
        check = connection.isConnected();
        break;
      default:
        throw new NotImplementedException(
          `${driver} ping check is not implemented yet`,
        );
    }

    return await promiseTimeout(timeout, check);
  }

Unlike get(‘type’) which may return undefined, the getDriver() method always returns a database driver (of the IDatabaseDriver interface), so the above switch case would no longer have an undefined case. Therefore, even in the default case, the user would no longer encounter a cryptic error message, i.e., undefined ping check is not implemented yet.

Let me know if the above proposal is good enough. I am happy to help create a pull request to fix this issue.

Thanks everyone!

Minimum reproduction code

In the sample 011-mirkoorm-app, make the following changes in health.module.ts to use the defineConfig helper from MikroOrm:

import { MikroOrmModule } from "@mikro-orm/nestjs";
import { Module } from "@nestjs/common";
import { HealthController } from "./health.controller";
import { TerminusModule } from "@nestjs/terminus";
import { defineConfig } from "@mikro-orm/mysql";

@Module({
  imports: [
    // MikroOrmModule.forRoot({
    //   type: 'mysql',
    //   dbName: 'test',
    //   user: 'root',
    //   password: 'root',
    //   host: '0.0.0.0',
    //   port: 3306,
    //   discovery: { warnWhenNoEntities: false }, // disable validation entities
    //   strict: true,
    // }),
    MikroOrmModule.forRoot(
      defineConfig({
        dbName: "test",
        user: "root",
        password: "root",
        host: "0.0.0.0",
        port: 3306,
        discovery: { warnWhenNoEntities: false }, // disable validation entities
        strict: true,
      })
    ),
    TerminusModule,
  ],
  controllers: [HealthController],
})
export class HealthModule {}

Run the app and make a GET request to the /health endpoint. The below cryptic error message would be returned:

undefined ping check is not implemented yet

Steps to reproduce

No response

Expected behavior

  • Should not throw a cryptic error message such as undefined ping check is not implemented yet
  • Should be able to work with the defineConfig helper

Package version

9.2.0

NestJS version

9.3.2

Node.js version

No response

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions