Skip to content

Commit ffffa6f

Browse files
authored
Merge pull request #146 from catalyst/issue145
issue #145: catch errors when indexing documents
2 parents 7a4c715 + 935b2fc commit ffffa6f

File tree

2 files changed

+67
-21
lines changed

2 files changed

+67
-21
lines changed

classes/search/activity.php

+33-21
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,40 @@ public function get_document($record, $options = []) {
5353
return false;
5454
}
5555

56-
$cms = new cms($cm->instance);
57-
$renderer = new renderer($cms);
58-
$value = $renderer->get_html();
59-
$title = $cms->get('name');
60-
$valueformat = FORMAT_HTML;
61-
62-
// Prepare associative array with data from DB.
63-
$doc = \core_search\document_factory::instance($record->id, $this->componentname, $this->areaname);
64-
$doc->set('title', content_to_text($title, false));
65-
$doc->set('content', content_to_text($value, $valueformat));
66-
$doc->set('contextid', $context->id);
67-
$doc->set('courseid', $record->course);
68-
$doc->set('owneruserid', \core_search\manager::NO_OWNER_ID);
69-
$doc->set('modified', $record->timemodified);
70-
71-
// Check if this document should be considered new.
72-
if (isset($options['lastindexedtime']) && ($options['lastindexedtime'] < $record->timecreated)) {
73-
// If the document was created after the last index time, it must be new.
74-
$doc->set_is_new(true);
75-
}
56+
// As mod_cms is a complicated activity that may use data from different modules dynamically,
57+
// there are many moving parts that potentially can break and throw errors/exception while doing global search indexing.
58+
// We would like to prevent that if possible.
59+
try {
60+
$cms = new cms($cm->instance);
61+
$renderer = new renderer($cms);
62+
$value = $renderer->get_html();
63+
$title = $cms->get('name');
64+
$valueformat = FORMAT_HTML;
65+
66+
// Prepare associative array with data from DB.
67+
$doc = \core_search\document_factory::instance($record->id, $this->componentname, $this->areaname);
68+
$doc->set('title', content_to_text($title, false));
69+
$doc->set('content', content_to_text($value, $valueformat));
70+
$doc->set('contextid', $context->id);
71+
$doc->set('courseid', $record->course);
72+
$doc->set('owneruserid', \core_search\manager::NO_OWNER_ID);
73+
$doc->set('modified', $record->timemodified);
74+
75+
// Check if this document should be considered new.
76+
if (isset($options['lastindexedtime']) && ($options['lastindexedtime'] < $record->timecreated)) {
77+
// If the document was created after the last index time, it must be new.
78+
$doc->set_is_new(true);
79+
}
7680

77-
return $doc;
81+
return $doc;
82+
83+
} catch (\Throwable $ex) {
84+
debugging('Error getting mod_cms document for global search.'
85+
. ' cmid: ' . $cm->id . ' ' . ' courseid: ' . $cm->course . ' '
86+
. $ex->getMessage(), DEBUG_DEVELOPER);
87+
88+
return false;
89+
}
7890
}
7991

8092
/**

tests/search/search_test.php

+34
Original file line numberDiff line numberDiff line change
@@ -384,4 +384,38 @@ public function test_check_access(): void {
384384
$this->setUser($user2);
385385
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($cms->id));
386386
}
387+
388+
/**
389+
* Test getting document catches errors.
390+
*
391+
* @return void
392+
* @covers ::get_document
393+
*/
394+
public function test_getting_document_catch_errors(): void {
395+
global $DB;
396+
397+
$searcharea = \core_search\manager::get_search_area($this->cmsareaid);
398+
$course = self::getDataGenerator()->create_course();
399+
400+
$generator = self::getDataGenerator()->get_plugin_generator('mod_cms');
401+
$record = new \stdClass();
402+
$record->course = $course->id;
403+
$record->customfield_overview = 'Test overview text 1';
404+
$record->typeid = $this->cmstype->get('id');
405+
$cms = $generator->create_instance_with_data($record);
406+
407+
// Let's break cms record so getting a document would throw an exception.
408+
$cms->typeid = 8888;
409+
$DB->update_record('cms', $cms);
410+
411+
// Test that an exception is not thrown, but debugging is triggered instead.
412+
$this->assertEmpty($searcharea->get_document($cms));
413+
$debuggingmessages = $this->getDebuggingMessages();
414+
$this->assertDebuggingCalled();
415+
416+
$this->assertStringContainsString(
417+
'Error getting mod_cms document for global search. cmid: ' . $cms->cmid . ' courseid: '. $course->id,
418+
reset($debuggingmessages)->message
419+
);
420+
}
387421
}

0 commit comments

Comments
 (0)