NestJSでError: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a stringと怒られた

# エラー時の状況

NestJSの環境構築時に起こったエラーの備忘録。

以下の記事を参考にしてNestJSの環境を構築して、`yarn start:dev`した時に怒られた。

https://zenn.dev/hasegawasatoshi/articles/8110ce79119dd0

```
Error: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string
```

:::note warn
お断り
記事の著者を攻める意図は全くありません。
むしろTypeORM 0.3系の情報なのでめちゃくちゃ感謝しています!
:::

# エラー原因の仮説

DBにうまく接続できていないのが原因そう。

- DBに接続する`database.module.ts`ファイルに不備がある?
- `docker-compose.yaml`の内容が間違っている?
  - `.env`ファイルの内容が間違っている?

## 仮説を検証してみる

一番簡単に対処できそうな設定ファイルをざっと見てみる。

> - `docker-compose.yaml`の内容が間違っている?
>   - `.env`ファイルの内容が間違っている?

タイポはしていなさそう。

```env: .env
POSTGRES_HOST="127.0.0.1"
POSTGRES_PORT="5432"
POSTGRES_DB="postgres"
POSTGRES_USER="root"
POSTGRES_PASSWORD="password"
```

```yaml: docker-compose.yaml
version: '3'

services:
  db:
    image: postgres
    volumes:
      - ./db/data:/var/lib/postgresql/data
      - ./db/postgres/initdb:/docker-entrypoint-initdb.d
    ports:
      - '${POSTGRES_PORT}:5432'
    environment:
      - TZ=Asia/Tokyo
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
```

## DBに接続する`database.module.ts`ファイルに不備がある?

タイポはなさそうなので`database.module.ts`の内容を見てみる。
うむ、記事と比較しても内容的に問題なさそう???

いや、もしかするとここで`.env`ファイルの設定を何かしらする必要がある?

```ts: database.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => {
        return {
          type: 'postgres',
          host: configService.get('POSTGRES_HOST'),
          port: configService.get('POSTGRES_PORT'),
          database: configService.get('POSTGRES_DB'),
          username: configService.get('POSTGRES_USER'),
          password: configService.get('POSTGRES_PASSWORD'),
          entities: [Todo],
          synchronize: true,
        };
      },
    }),
  ],
})
export class DatabaseModule {}
```

### `.env`ファイルの設定が必要なのかググってみる

すると`app.module.ts`に環境変数の設定をしている記事を見つけた。

https://zenn.dev/waddy/articles/nestjs-configuration-service#1%2C2%2C3%3A-nestjs-%E3%81%8C-.env-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%A8%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%82%92%E5%90%88%E4%BD%93%E3%81%97%E3%81%A6%E3%81%8F%E3%82%8C%E3%82%8B%E3%81%AE%E3%81%A7%E3%81%9D%E3%82%8C%E3%81%AB%E4%B9%97%E3%81%A3%E3%81%8B%E3%82%8B

今回は、`database.module.ts`に環境変数の設定を追加しても問題なさそうか試してみる。

```diff_typescript: database.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { Todo } from 'src/todo/entities/todo.entity';

@Module({
  imports: [
+    TypeOrmModule.forRootAsync({
+      imports: [
+        ConfigModule.forRoot({
+          envFilePath: ['.env'],
+        }),
+      ],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => {
        return {
          type: 'postgres',
          host: configService.get('POSTGRES_HOST'),
          port: configService.get('POSTGRES_PORT'),
          database: configService.get('POSTGRES_DB'),
          username: configService.get('POSTGRES_USER'),
          password: configService.get('POSTGRES_PASSWORD'),
          entities: [Todo],
          synchronize: true,
        };
      },
    }),
  ],
})
export class DatabaseModule {}
```

これでログを見てみると、解消されていました!

🎉🎉🎉

# 原因

`.env`ファイルの読み込みの設定が、`app.module.ts`に紐付いていないのが原因でした。

# Source and Thanks

https://zenn.dev/hasegawasatoshi/articles/8110ce79119dd0

https://zenn.dev/waddy/articles/nestjs-configuration-service