Task Output Sometimes null

I’m running into an issue inside of a custom task I have created with the $this->output being null sometimes.

If I run the task from the CLI or from the Task interface it works as expected but from a page controller if I do something like:

$command = app(Command::class, ['param' => $value]);
$this->app->executeCommand($command);

The task is executed however I cannot log any output from the CommandHandler. Also, it does not log the execution in the dashboard task display at all.

Is there a different way I should be triggering a task from code?

Thanks!

Can you be more specific about what you’re needing tasks for? This sounds more like a job for a controller method if you just need to encapsulate functionality, or a command bus command if you’re wanting things to happen asynchronously.

Tasks are not really meant for being used on request like this so there isn’t really much tooling for making it happen. That said if you really want this to work this way you can see how the core triggers tasks here: concretecms/tasks.php at develop · concretecms/concretecms · GitHub

1 Like

There’s more in the tasks than just the definitions of the input, the command and the handlers, etc… The support classes for the tasks themselves take care of injecting that output object into the command handlers, so if you don’t run them using the support classes (and instead just reference the command directly) it’s not going to have that output.

So you have two choices - 1 you can just run the command directly and have no access to output (since most commands in a command bus won’t really do “output” anyway or 2 you can use the support classes to instantiate the tasks with output and run them that way.

Number 2 is actually not quite as difficult as it may sound. In the latest develop branch we’ve made it easier, too. Here’s an example of the a new Dashboard page in 9.2 (coming soon) that might be doing exactly what you’re trying to do.

This is the Site Health page. It presents a number of tasks in the special site health category.

(these “reports” are just tasks.)

When you click on the Run report button, behind the scenes from this custom dashboard page a task is run.

The sub-tasks/commands that make up this report are even displayed in the page. From within the Dashboard controller the code that runs the task is pretty straightforward. You can see it in concrete/controllers/single_page/dashboard/welcome/health.php. Here it is adapted for use with some kind of hard-coded custom task.

use Concrete\Core\Command\Task\TaskService;
use Concrete\Core\Command\Task\Traits\DashboardTaskRunnerTrait;

// snip...

use DashboardTaskRunnerTrait; // This adds the `executeTask` method into the controller.

$task = $this->app->make(TaskService::class)->getByHandle('my_custom_task');
$controller = $task->getController();
$this->executeTask($task);

This will execute the task with the Dashboard task output present.

If you don’t have access to the latest develop branch to work with this, and you’re wondering what that DashboardTaskRunnerTrait is, here’s the contents of it. If you’re running an older version of v9 you can probably just use this code directly - we just added a trait for it to make it easier for developers going forward:

    $controller = $task->getController();
    $runner = $controller->getTaskRunner($task, new Input());
    $handler = $this->app->make($runner->getTaskRunnerHandler());
    $handler->boot($runner);

    $contextFactory = $this->app->make(ContextFactory::class);
    $context = $contextFactory->createDashboardContext($runner);

    $handler->start($runner, $context);
    $handler->run($runner, $context);

Hope this helps!

1 Like