NESTJSスケジュールされたジョブによる歩哨の統合


積分後@ntegral/nestjs-sentry 私のNESTJSプロジェクトでは、ログインしていないログにエラーがあることを知りました.
調査の少し後、私はnestjsのInterceptorExceptionFilter sは実行コンテキストがどうにか要求されるという考えのまわりに構築されます.すなわち、これらの構造体は、例えばHTTPやGraphqlを通してサーバへの外部リクエストによってエラーが発生すると予想します.
残念ながら、Cron デコレータ@nestjs/schedule , 私のコードは実際に外部リクエストによって引き起こされていないので、これらのコンテキストでスローされたエラーは、通常のインターセプターまたは例外フィルターパイプラインにバブルアップしないようです.
これを解決するために、私はこれからインスピレーションを取りましたStackOverflow answer 私のラップを使用するデコレータを作成するにはCron キャッチされたエラーを直接監視するエラーハンドラーのメソッドです.
次のようになります.
// decorators/sentry-overwatch.decorator.ts

import { Inject } from "@nestjs/common";
import { SentryService } from "@ntegral/nestjs-sentry";

export const SentryOverwatchAsync = () => {
  const injectSentry = Inject(SentryService);

  return (
    target: any,
    _propertyKey: string,
    propertyDescriptor: PropertyDescriptor,
  ) => {
    injectSentry(target, "sentry");
    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
    const originalMethod: () => Promise<void> = propertyDescriptor.value;
    propertyDescriptor.value = async function (...args: any[]) {
      try {
        return await originalMethod.apply(this, args);
      } catch (error) {
        const sentry = this.sentry as SentryService;
        sentry.instance().captureException(error);
        throw error;
      }
    };
  };
};
この特定の関数は、async関数を装飾するように設計されています.非同期バージョンでは、asyncpropertyDescriptor.value 定義とawait 呼び出すときoriginalMethod .
もう少し仕事をすれば、戻り値が約束であるかどうかを検出するために、より一般的なものを書くことができます.
このようにオリジナルの関数をラップできます.
// decorators/cron.decorator.ts

// Decorator ordering is important here. Swapping the order
// results in Nest failing to recognize this as a scheduled
// job
@Cron("*/5 * * * *")
@SentryOverwatchAsync()
async scheduledTask(): Promise<void> {
  // ...
}
しかし、今私は追加する必要があります@SentryOverwatchAsync() 私が宣言するたびに@Cron 予定の仕事.少しいらいらさせてください、そして、私は私がある点で忘れそうであると確信します.
使用decorator composition 私は私自身のバージョンを再エクスポートすることを決めた@Cron 自分の新しいカスタムデコレータでネイティブネストデコレータをパッケージするデコレータ
import { applyDecorators } from "@nestjs/common";
import { Cron as NestCron, CronOptions } from "@nestjs/schedule";

import { SentryOverwatchAsync } from "./sentry-overwatch.decorator";

export const Cron = (cronTime: string | Date, options?: CronOptions) => {
  // Ordering is important here, too!
  // The order these must appear in seems to be the reverse of
  // what you'd normally expect when decorating functions
  // declaratively. Likely because the order you specify here
  // is the order the decorators will be applied to the 
  // function in.
  return applyDecorators(SentryOverwatchAsync(), NestCron(cronTime, options));
};
今私がする必要があるすべての私の使用のすべてを交換するCron 私の内部にCron デコレータと私は、完全な歩哨見張りをします.
心の平和:達成!