Closed (fixed)
Project:
Fuzzy Search
Version:
6.x-1.5
Component:
Code
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
13 Dec 2011 at 20:50 UTC
Updated:
31 Jan 2012 at 02:31 UTC
I'm not sure how the tables got mismatched. It could happen during a backup restore or something... But in any case, during cron the dreaded Invalid argument supplied for foreach() in /.../taxonomy.module on line 1241 error appears because of this code:
/**
* Implementation of hook_cron().
*/
function fuzzysearch_cron() {
$query = db_query_range("SELECT nid FROM {fuzzysearch_index_queue}", 0, variable_get('fuzzysearch_index_cron', 150));
while ($result = db_fetch_object($query)) {
fuzzysearch_index($result->nid);
}
}
If there are nid's returned by this query, and they are not present in the node table, non-existent nid's get sent to node_load, thus causing the error.
Replacing with this heavier function works, but it might be better if the else clause were compiled into a cleaner compound query to improve performance..
/**
* Implementation of hook_cron().
*/
function fuzzysearch_cron() {
//build a list of nodes in the node table
$query = db_query("SELECT nid FROM {node}");
$nodes = array();
while ($result = db_fetch_object($query)) {
$nodes[] = $result->nid;
}
//run through queued nodes, eliminating those no longer in node table
$query = db_query_range("SELECT nid FROM {fuzzysearch_index_queue}", 0, variable_get('fuzzysearch_index_cron', 150));
while ($result = db_fetch_object($query)) {
if(in_array($result->nid,$nodes)){
fuzzysearch_index($result->nid);
}else{
db_query("DELETE FROM {fuzzysearch_index} WHERE nid = %d", $result->nid);
db_query("DELETE FROM {fuzzysearch_index_queue} WHERE nid = %d", $result->nid);
}
}
}
Comments
Comment #1
awolfey commentedMy guess is that something is deleting your nodes in a way that doesn't invoke nodeapi.
I think the place to check if the node still exists before indexing is in fuzzysearch_index. It would be reusable code there.
Comment #2
awolfey commentedWrap node_load() in an if to make sure it loads. If not, delete the row from the queue and return.
Comment #3
tmsimont commentedi just updated my solution -- i had a bug in the code i posted.
the issue with wrapping node_load in an if is that the function will return a malformed node even if there's no nid to match... this is fixed in D7, but is a big issue in D6 which often leads to this error. see: http://drupal.org/node/839654
I know that the mismatch occurred during a content backup or swap -- I've been in and out of the content tables a few times. I don't think it's too uncommon for nodes to get deleted without having gone through the nodeapi.
i'm not sure if you need to update your module to account for such situations, but it might be helpful to others that run into this issue.
Comment #4
tmsimont commentedthe downside to check for the node still existing in fuzzysearch_index() is that it would require a lot of additional queries... 1 for each node instead of 1 query for all nids to start... but then again, you wouldn't have to call in_array() so many times... maybe a whole new function is needed, like "fuzzysearch_clean_nonexistent_nodes()"
Comment #5
awolfey commentedThis should do it at the top of fuzzysearch_index();
If you want to submit a patch please do it against the dev version. Thanks
Comment #6
awolfey commentedFixed. This works.
Comment #7.0
(not verified) commentedfixed bug in solution