かきノート

【Laravel】$schedule->command にて、cron メソッドの引数が不正だった場合、全てのコマンドが実行されない。

July 20, 2021 • ☕️ 3 min read

【 環境 】
Laravel のバージョン: 8.16.1
PHP のバージョン: 7.4.7
MySQL のバージョン: 5.7

Laravel のスケジューラについて

Laravel の $schedule->command にて、バッチが起動する間隔を「->everyFiveMinutes()」「->dailyAt(‘13:00’)」といったメソッドではなく、
「->cron(’* 0 * * *’)」と、cron で設定する事が出来ます。

具体的には、以下のようなコード。

    // 間隔を指定したメソッド(5分おき、等)を指定する
    $schedule->command(Batch01Command::class)
        ->everyFiveMinutes();

    // cron メソッドを使用する
    $schedule->command(Batch02Command::class)
        ->cron('* * * * *');

「cronメソッドの引数に渡す値が不正だった場合、どんな挙動になるの?」(起動スケジュールをコンフィグで自由に設定できるようにしたかったので、設定が不正だった時の挙動を把握しておきたかった)
というのが気になったので、実験。

以下のようなコードを書いてみました。

実験

app\Console\Kernel.php

    protected function schedule(Schedule $schedule)
    {
        $this->scheduleExecuteBatches($schedule);
    }

    private function scheduleExecuteBatches(Schedule $schedule)
    {
        $this->scheduleExecuteCommand01($schedule);
        $this->scheduleExecuteCommand02($schedule);
        $this->scheduleExecuteCommand03($schedule);
    }

    private function scheduleExecuteCommand01(Schedule $schedule)
    {
        try {
            $schedule->command(Batch01Command::class)
                ->everyMinute()
                ->runInBackground();

        } catch (\Exception $e) {
            $this->warn(__METHOD__ . ':' . $e->getMessage());
            \Log::warning(__METHOD__ . ':' . $e->getMessage());
        }
    }

    private function scheduleExecuteCommand02(Schedule $schedule)
    {
        try {
            $schedule->command(Batch02Command::class)
                ->cron('* * * * *aaa')
                ->runInBackground();

        } catch (\Exception $e) {
            $this->warn(__METHOD__ . ':' . $e->getMessage());
            \Log::warning(__METHOD__ . ':' . $e->getMessage());
        }
    }

    private function scheduleExecuteCommand03(Schedule $schedule)
    {
        try {
            $schedule->command(Batch03Command::class)
                ->cron('* * * * *')
                ->runInBackground();

        } catch (\Exception $e) {
            $this->warn(__METHOD__ . ':' . $e->getMessage());
            \Log::warning(__METHOD__ . ':' . $e->getMessage());
        }
    }

実験の趣旨

  • cron メソッドへの引数が不正だった時、その次に実行予定のバッチは実行されるの?(scheduleExecuteCommand03 は実行されるの?)
  • 設定が不正だった時、Try-catch で捕捉できる? その時のエラーメッセージは?(scheduleExecuteCommand02 のエラー内容は?)

一番最初の Batch01Command は実行されるだろうけど、その後の処理はどうなるの? という意図。

実験結果

コマンド

php artisan schedule:run

ログの内容

[2021-07-20 07:00:38] local.ERROR: Invalid CRON field value *aaa at position 4 {"exception":"[object] (InvalidArgumentException(code: 0): Invalid CRON field value *aaa at position 4 at /var/www/html/my-laravel-app/vendor/dragonmantank/cron-expression/src/Cron/CronExpression.php:158)
[stacktrace]
#0 /var/www/html/my-laravel-app/vendor/dragonmantank/cron-expression/src/Cron/CronExpression.php(139): Cron\\CronExpression->setPart(4, '*aaa')
#1 /var/www/html/my-laravel-app/vendor/dragonmantank/cron-expression/src/Cron/CronExpression.php(114): Cron\\CronExpression->setExpression('* * * * *aaa')

(以下略)

後続の処理どころか、正しい設定をされているはずの Batch01Command すらも実行されなかった。
Try catch で囲もうが、お構いなしです。

ログの内容を確認しましたが、別に Try-catch で囲まなくても出力されたので、Try-catch の管轄外なのではないかと思われます。

という事で、結論。

Schedule の cron メソッドの引数が不正だった時、全てのコマンドが実行されない。
しかも、Try catch で捕捉不可。

スケジューラを起動した瞬間にすぐに分かるようになっているので、挙動としてはある意味正しいのかもしれない。


Relative Posts:

【Laravel】schedule からコールされる command は、後続のメソッド次第で同期的に処理されたり非同期で処理されたりする(runInBackground)

July 21, 2021

【Laravel】(Alpine)Redis を使う時のライブラリ、Predis と PhpRedis を試してみる

July 16, 2021

福岡の物流エンジニアが、七転び八起きしたあと九回転び、寝っ転がったまま何かやってる事を垂れ流しているブログ

RotateLinkImg-iconRotateLinkImg-iconRotateLinkImg-iconRotateLinkImg-icon