studioespresso / craft-scout

Craft Scout provides a simple solution for adding full-text search to your entries. Scout will automatically keep your search indexes in sync with your entries.
MIT License
81 stars 54 forks source link

Updating from control panel occasionally yields error ”Call to a member function update() on null“ #121

Closed furioursus closed 10 months ago

furioursus commented 4 years ago

I’m running the latest version of Scout (2.1.2) and Craft (3.3.15). If I submit my indices from the command line, they all process as normal and things seem to work just fine.

However, I find that some of my entries will fail when the authors attempt to update their entry in the control panel with the following stacktrace in queue.log:

2019-11-20 13:29:06 [-][1][-][error][Error] Error: Call to a member function update() on null in /Users/ckennedy/Sites/oaklandca.gov/vendor/rias/craft-scout/src/jobs/MakeSearchable.php:34
Stack trace:
#0 /Users/ckennedy/Sites/oaklandca.gov/vendor/yiisoft/yii2-queue/src/Queue.php(214): rias\scout\jobs\MakeSearchable->execute(Object(craft\queue\Queue))
#1 /Users/ckennedy/Sites/oaklandca.gov/vendor/yiisoft/yii2-queue/src/cli/Queue.php(147): yii\queue\Queue->handleMessage('34312', 'O:30:"rias\\scou...', '300', 1)
#2 /Users/ckennedy/Sites/oaklandca.gov/vendor/craftcms/cms/src/queue/Queue.php(96): yii\queue\cli\Queue->handleMessage('34312', 'O:30:"rias\\scou...', '300', 1)
#3 /Users/ckennedy/Sites/oaklandca.gov/vendor/craftcms/cms/src/controllers/QueueController.php(86): craft\queue\Queue->run()
#4 [internal function]: craft\controllers\QueueController->actionRun()
#5 /Users/ckennedy/Sites/oaklandca.gov/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#6 /Users/ckennedy/Sites/oaklandca.gov/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array)
#7 /Users/ckennedy/Sites/oaklandca.gov/vendor/craftcms/cms/src/web/Controller.php(187): yii\base\Controller->runAction('run', Array)
#8 /Users/ckennedy/Sites/oaklandca.gov/vendor/yiisoft/yii2/base/Module.php(528): craft\web\Controller->runAction('run', Array)
#9 /Users/ckennedy/Sites/oaklandca.gov/vendor/craftcms/cms/src/web/Application.php(299): yii\base\Module->runAction('queue/run', Array)
#10 /Users/ckennedy/Sites/oaklandca.gov/vendor/craftcms/cms/src/web/Application.php(565): craft\web\Application->runAction('queue/run', Array)
#11 /Users/ckennedy/Sites/oaklandca.gov/vendor/craftcms/cms/src/web/Application.php(278): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#12 /Users/ckennedy/Sites/oaklandca.gov/vendor/yiisoft/yii2/base/Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
#13 /Users/ckennedy/Sites/oaklandca.gov/web/index.php(21): yii\base\Application->run()
#14 /Users/ckennedy/.composer/vendor/laravel/valet/server.php(158): require('/Users/ckennedy...')
#15 {main}

In this example, I have disabled literally every field, facet, etc., in the index setup as shown here and flushed all the old settings dev_news which this should post to:

\rias\scout\ScoutIndex::create(getenv('ENVIRONMENT') . '_news')
  ->criteria(function (\craft\elements\db\EntryQuery $query) {
    return $query
      ->section(['news']);
  }),

I'm a bit stymied about how to proceed. I can alleviate the problem when it arises by updating the indices from the command line, and things work as normal, but that incurs a HUGE overhead of operations as the process touches literally every other section's index on the site.

Is there anything I might be missing here that needs to be set or declared?

furioursus commented 4 years ago

I’ll also add that if an entry will not save to the index with that error, I can save it as a new entry in Craft and the new entry will push to the index without a problem!

I’m also happy to provide our affected db if you need to troubleshoot at any point.

khalwat commented 4 years ago

So what's happening is here:

https://github.com/riasvdv/craft-scout/blob/master/src/jobs/MakeSearchable.php#L34

$engine can apparently come back as null. Without looking deeply into why, or whether that's by design, a simple fix we can probably do is change the execute() function to be:

    public function execute($queue)
    {
        if (!$element = $this->getElement()) {
            return;
        }

        $engine = $element->searchableUsing()->first(function (Engine $engine) {
            return $engine->scoutIndex->indexName === $this->indexName;
        });

        // Handle $engine coming back as null as per: https://github.com/riasvdv/craft-scout/issues/121 -- aaw/2020.01.02
        if (!$engine) {
            return;
        }

        $engine->update($element);

        if ($this->propagate) {
            $element->searchableRelations();
        }
    }

I can do a PR if you're still around @riasvdv -- probably just as easy for you to apply the fix tho, if you're up for it.

riasvdv commented 4 years ago

I'm so sorry, completely lost track of this issue, I've added this fix in 2.1.4