October: registerSchedule is failing without error when a type hint is present

Created on 18 Nov 2019  路  6Comments  路  Source: octobercms/october

  • OctoberCMS Build: 459
  • PHP Version: 7.3.10

I noticed some strange behaviour when using the registerSchedule method with custom console commands:

class Plugin extends PluginBase
{
    public function boot()
    {
        // This registers gdpr:cleanup
        $this->registerConsoleCommand('gdpr.cleanup', CleanUp::class);
    }

    public function registerSchedule($schedule)
    {
        $schedule->call('gdpr:cleanup')->everyMinute();
    }
}

Registring the command and the schedule returns in the following output:

$ php artisan gdpr:cleanup  # command works!
Cleaning up...

$ php artisan schedule:run -v
Running scheduled command: gdpr:cleanup


  [ReflectionException]                   
  Function gdpr:cleanup() does not exist  

Exception trace:
 () at /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:136
 ReflectionFunction->__construct() at /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:136
 Illuminate\Container\BoundMethod::getCallReflector() at /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:115
 Illuminate\Container\BoundMethod::getMethodDependencies() at /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:29
 Illuminate\Container\BoundMethod::Illuminate\Container\{closure}() at /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:75
 Illuminate\Container\BoundMethod::callBoundMethod() at /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:31
 Illuminate\Container\BoundMethod::call() at /app/vendor/laravel/framework/src/Illuminate/Container/Container.php:549
 Illuminate\Container\Container->call() at /app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/CallbackEvent.php:74
 Illuminate\Console\Scheduling\CallbackEvent->run() at /app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleRunCommand.php:59
 Illuminate\Console\Scheduling\ScheduleRunCommand->handle() at n/a:n/a
 call_user_func_array() at /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:29
 Illuminate\Container\BoundMethod::Illuminate\Container\{closure}() at /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:87
 Illuminate\Container\BoundMethod::callBoundMethod() at /app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:31
 Illuminate\Container\BoundMethod::call() at /app/vendor/laravel/framework/src/Illuminate/Container/Container.php:549
 Illuminate\Container\Container->call() at /app/vendor/laravel/framework/src/Illuminate/Console/Command.php:183
 Illuminate\Console\Command->execute() at /app/vendor/symfony/console/Command/Command.php:264
 Symfony\Component\Console\Command\Command->run() at /app/vendor/laravel/framework/src/Illuminate/Console/Command.php:170
 Illuminate\Console\Command->run() at /app/vendor/symfony/console/Application.php:874
 Symfony\Component\Console\Application->doRunCommand() at /app/vendor/symfony/console/Application.php:228
 Symfony\Component\Console\Application->doRun() at /app/vendor/symfony/console/Application.php:130
 Symfony\Component\Console\Application->run() at /app/vendor/laravel/framework/src/Illuminate/Console/Application.php:88
 Illuminate\Console\Application->run() at /app/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:121
 Illuminate\Foundation\Console\Kernel->handle() at /app/artisan:35                                         

It looks like the command is not found. But this should work, right?

What's even stranger, when adding a type hint to the registerSchedule method:

    // use Illuminate\Console\Scheduling\Schedule;

    public function registerSchedule(Schedule $schedule)
    {
        $schedule->call('gdpr:cleanup')->everyMinute();
    }

The method is not longer called at all!

$ php artisan schedule:run -v
No scheduled commands are ready to run.

I'll try to dig into this and propose a PR.

Review Needed Unconfirmed Bug

All 6 comments

Well, looks like you need to use command, not call :man_facepalming:

Nevertheless, adding the type hint still skips the registration altogether.

Edit: Alright, that's because of the defined base method that doesn't have the type hint. Somehow the error just gets swallowed up.

@tobias-kuendig is there still an issue here? Perhaps a change could be made to the docs?

No, the docs are fine. I just didn't see the wrong call in my code.

The other issue I noticed still persists. Adding a type hint to the registerSchedule method make's it incompatible with the base class method. This is obviously not fixable by itself, but I guess an error message would be useful? Currently it silently fails and the schedule is not registered.

@tobias-kuendig it's possible that is being treated as a fatal error in plugin.php which results in October choosing not to load the plugin. I think we might have an error log entry being added though, @bennothommo?

@LukeTowers that's correct - if it was caught by the functionality that checks parse errors in plugins, it should be coming up in the error logs.

Alright, I just checked, this is already happening:

Plugin X could not be instantiated. {"message":"Declaration of Plugin::registerSchedule(Illuminate\Console\Scheduling\Schedule $schedule) should be compatible with System\Classes\PluginBase::registerSchedule($schedule)"

I was expecting an error visible in the console, printed to stderr. But I guess this approach makes sense since the plugin code is in fact not valid.

All good!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

axomat picture axomat  路  3Comments

oppin picture oppin  路  3Comments

m49n picture m49n  路  3Comments

mittultechnobrave picture mittultechnobrave  路  3Comments

dunets picture dunets  路  3Comments