nestjs/schedule

Using `env` variables in the `@Cron` handle

Mortefal opened this issue · 2 comments

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

When using the @Cron function to create a scheduled job, it fails to read variables from env. I

Minimum reproduction code

https://github.com/Mortefal/cron-proof

Steps to reproduce

  1. npm i
  2. create .env file and add CRON_TEST_STRING with a valid cron value. eg. */10 * * * * *
  3. npm run start
  4. expect this error:

node_modules\cron\dist\time.js:360 source = source.toLowerCase(); ^ TypeError: Cannot read properties of undefined (reading 'toLowerCase')

Where i would expect it to register both cron jobs in app.service.ts.

Expected behavior

Where i would expect it to register both cron jobs in app.service.ts.

Seems like the @Cron function runs without access to the process.env

Package version

^4.0.0

NestJS version

^10.0.0

Node.js version

v18.12.1

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

No response

I'll let the Nest maintainers comment on using environment variables in the Cron decorator. However, this may be due to the AppService decorators being loaded before the ConfigModule loads the .env file.

Here's a workaround using the dynamic scheduler API in the meantime:

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Cron, CronExpression, SchedulerRegistry } from '@nestjs/schedule';
import { CronJob } from 'cron';

@Injectable()
export class AppService {
  constructor(
    private configService: ConfigService,
    private schedulerRegistry: SchedulerRegistry,
  ) {
    this.schedulerRegistry.addCronJob(
      'getFoo',
      CronJob.from({
        cronTime: this.configService.get('CRON_TEST_STRING'),
        start: true,
        onTick: () => {
          this.getFoo();
        },
      }),
    );
  }

  @Cron(CronExpression.EVERY_10_SECONDS)
  getHello(): string {
    console.log('Hello World!');
    return 'Hello World!';
  }

  getFoo(): string {
    console.log('Foo');
    return 'Foo';
  }
}

I'll let the Nest maintainers comment on using environment variables in the Cron decorator. However, this may be due to the AppService decorators being loaded before the ConfigModule loads the .env file.

Correct.

For this, you should use the dynamic cron jobs API https://docs.nestjs.com/techniques/task-scheduling#dynamic-cron-jobs