[tracker: 17/21] propagate an error if ontology file contain parsing errors
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker: 17/21] propagate an error if ontology file contain parsing errors
- Date: Tue, 5 Oct 2021 14:16:17 +0000 (UTC)
commit 38c754e447a98e35b0c08c1656616b411de45dfc
Author: Abanoub Ghadban <abanoub gdb gmail com>
Date: Fri Aug 20 22:20:49 2021 +0200
propagate an error if ontology file contain parsing errors
It doesn't stop parsing when an error is found. Instead it prints a warning about the error and continue
parsing.
After parsing all ontologies and before making any changes to the db, it propagate an error if one or
more parsing errors are faced while parsing.
This approach prints all problems in the ontology file at once, so the developer can fix them all before
needing to run tracker many times.
src/libtracker-data/tracker-data-manager.c | 144 ++++++++++++++++++-----------
1 file changed, 92 insertions(+), 52 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 4da39ebd8..e1853c34e 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -804,6 +804,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
goffset object_line_no,
goffset object_column_no,
gboolean in_update,
+ gboolean *loaded_successfully,
GPtrArray *seen_classes,
GPtrArray *seen_properties,
GError **error)
@@ -811,6 +812,8 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
gchar *object_location = g_strdup_printf("%s:%" G_GOFFSET_FORMAT ":%" G_GOFFSET_FORMAT,
ontology_path, object_line_no, object_column_no);
+ *loaded_successfully = TRUE;
+
if (g_strcmp0 (predicate, RDF_TYPE) == 0) {
if (g_strcmp0 (object, RDFS_CLASS) == 0) {
TrackerClass *class;
@@ -839,7 +842,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
subject, NULL, error);
if (!subject_id) {
g_prefix_error (error, "%s:", object_location);
- goto out;
+ goto fail;
}
class = tracker_class_new (FALSE);
@@ -890,7 +893,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
NULL, error);
if (!subject_id) {
g_prefix_error (error, "%s:", object_location);
- goto out;
+ goto fail;
}
property = tracker_property_new (FALSE);
@@ -915,7 +918,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
property = tracker_ontologies_get_property_by_uri (manager->ontologies, subject);
if (property == NULL) {
g_critical ("%s: Unknown property %s", object_location, subject);
- goto out;
+ goto fail;
}
if (in_update) {
@@ -935,7 +938,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
if (err) {
g_propagate_prefixed_error (error, err, "%s: ", object_location);
- goto out;
+ goto fail;
}
}
@@ -980,7 +983,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
class = tracker_ontologies_get_class_by_uri (manager->ontologies, subject);
if (class == NULL) {
g_critical ("%s: Unknown class %s", object_location, subject);
- goto out;
+ goto fail;
}
is_new = tracker_class_get_is_new (class);
@@ -994,7 +997,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
super_class = tracker_ontologies_get_class_by_uri (manager->ontologies,
object);
if (super_class == NULL) {
g_critical ("%s: Unknown class %s", object_location, object);
- goto out;
+ goto fail;
}
while (*super_classes) {
@@ -1042,13 +1045,16 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
tracker_class_add_super_class (class, super_class);
}
+ if (*error)
+ goto fail;
+
goto out;
}
super_class = tracker_ontologies_get_class_by_uri (manager->ontologies, object);
if (super_class == NULL) {
g_critical ("%s: Unknown class %s", object_location, object);
- goto out;
+ goto fail;
}
tracker_class_add_super_class (class, super_class);
@@ -1060,7 +1066,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
if (class == NULL) {
g_critical ("%s: Unknown class %s", object_location, subject);
- goto out;
+ goto fail;
}
tracker_class_set_notify (class, (strcmp (object, "true") == 0));
@@ -1076,36 +1082,21 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
if (class == NULL) {
g_critical ("%s: Unknown class %s", object_location, subject);
- goto out;
+ goto fail;
}
property = tracker_ontologies_get_property_by_uri (manager->ontologies, object);
if (property == NULL) {
-
- /* In this case the import of the TTL will still make the introspection
- * have the URI set as a nrl:domainIndex for class. The critical
- * will have happened, but future operations might not cope with this
- * situation. TODO: add error handling so that the entire ontology
- * change operation is discarded, for example ignore the entire
- * .ontology file and rollback all changes that happened. I would
- * prefer a hard abort() here over a g_critical(), to be honest.
- *
- * Of course don't we yet allow just anybody to alter the ontology
- * files. So very serious is this lack of thorough error handling
- * not. Let's just not make mistakes when changing the .ontology
- * files for now. */
-
- g_critical ("%s: Unknown property %s for nrl:domainIndex in %s."
- "Don't release this .ontology change!",
+ g_critical ("%s: Unknown property %s for nrl:domainIndex in %s.",
object_location, object, subject);
- goto out;
+ goto fail;
}
if (tracker_property_get_multiple_values (property)) {
g_critical ("%s: Property %s has multiple values while trying to add it as
nrl:domainIndex in %s, this isn't supported",
object_location, object, subject);
- goto out;
+ goto fail;
}
properties = tracker_ontologies_get_properties (manager->ontologies, &n_props);
@@ -1158,7 +1149,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
property = tracker_ontologies_get_property_by_uri (manager->ontologies, subject);
if (property == NULL) {
g_critical ("%s: Unknown property %s", object_location, subject);
- goto out;
+ goto fail;
}
is_new = tracker_property_get_is_new (property);
@@ -1172,7 +1163,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
super_property = tracker_ontologies_get_property_by_uri (manager->ontologies,
object);
if (super_property == NULL) {
g_critical ("%s: Unknown property %s", object_location, object);
- goto out;
+ goto fail;
}
while (*super_properties) {
@@ -1219,13 +1210,16 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
tracker_property_add_super_property (property, super_property);
}
+ if (*error)
+ goto fail;
+
goto out;
}
super_property = tracker_ontologies_get_property_by_uri (manager->ontologies, object);
if (super_property == NULL) {
g_critical ("%s: Unknown property %s", object_location, object);
- goto out;
+ goto fail;
}
tracker_property_add_super_property (property, super_property);
@@ -1237,13 +1231,13 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
property = tracker_ontologies_get_property_by_uri (manager->ontologies, subject);
if (property == NULL) {
g_critical ("%s: Unknown property %s", object_location, subject);
- goto out;
+ goto fail;
}
domain = tracker_ontologies_get_class_by_uri (manager->ontologies, object);
if (domain == NULL) {
g_critical ("%s: Unknown class %s", object_location, object);
- goto out;
+ goto fail;
}
is_new = tracker_property_get_is_new (property);
@@ -1263,6 +1257,10 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
error);
}
}
+
+ if (*error)
+ goto fail;
+
goto out;
}
@@ -1274,7 +1272,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
property = tracker_ontologies_get_property_by_uri (manager->ontologies, subject);
if (property == NULL) {
g_critical ("%s: Unknown property %s", object_location, subject);
- goto out;
+ goto fail;
}
if (tracker_property_get_is_new (property) != in_update) {
@@ -1286,14 +1284,14 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
&err);
if (err) {
g_propagate_prefixed_error (error, err, "%s: ", object_location);
- goto out;
+ goto fail;
}
}
range = tracker_ontologies_get_class_by_uri (manager->ontologies, object);
if (range == NULL) {
g_critical ("%s: Unknown class %s", object_location, object);
- goto out;
+ goto fail;
}
tracker_property_set_range (property, range);
@@ -1303,7 +1301,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
property = tracker_ontologies_get_property_by_uri (manager->ontologies, subject);
if (property == NULL) {
g_critical ("%s: Unknown property %s", object_location, subject);
- goto out;
+ goto fail;
}
if (atoi (object) == 0) {
@@ -1311,7 +1309,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
TRACKER_SPARQL_ERROR,
TRACKER_SPARQL_ERROR_TYPE,
"Property nrl:maxCardinality only accepts integers greater than 0");
- goto out;
+ goto fail;
}
if (tracker_property_get_is_new (property) != in_update) {
@@ -1323,7 +1321,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
&err);
if (err) {
g_propagate_prefixed_error (error, err, "%s: ", object_location);
- goto out;
+ goto fail;
}
}
@@ -1341,7 +1339,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
property = tracker_ontologies_get_property_by_uri (manager->ontologies, subject);
if (property == NULL) {
g_critical ("%s: Unknown property %s", object_location, subject);
- goto out;
+ goto fail;
}
tracker_property_set_indexed (property, (strcmp (object, "true") == 0));
@@ -1351,24 +1349,24 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
property = tracker_ontologies_get_property_by_uri (manager->ontologies, subject);
if (property == NULL) {
g_critical ("%s: Unknown property %s", object_location, subject);
- goto out;
+ goto fail;
}
secondary_index = tracker_ontologies_get_property_by_uri (manager->ontologies, object);
if (secondary_index == NULL) {
g_critical ("%s: Unknown property %s", object_location, object);
- goto out;
+ goto fail;
}
if (!tracker_property_get_indexed (property)) {
g_critical ("%s: nrl:secondaryindex only applies to nrl:indexed properties",
object_location);
- goto out;
+ goto fail;
}
if (tracker_property_get_multiple_values (property) ||
tracker_property_get_multiple_values (secondary_index)) {
g_critical ("%s: nrl:secondaryindex cannot be applied to properties with
nrl:maxCardinality higher than one", object_location);
- goto out;
+ goto fail;
}
tracker_property_set_secondary_index (property, secondary_index);
@@ -1378,7 +1376,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
property = tracker_ontologies_get_property_by_uri (manager->ontologies, subject);
if (property == NULL) {
g_critical ("%s: Unknown property %s", object_location, subject);
- goto out;
+ goto fail;
}
tracker_property_set_fulltext_indexed (property,
@@ -1389,7 +1387,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
namespace = tracker_ontologies_get_namespace_by_uri (manager->ontologies, subject);
if (namespace == NULL) {
g_critical ("%s: Unknown namespace %s", object_location, subject);
- goto out;
+ goto fail;
}
if (tracker_namespace_get_is_new (namespace) != in_update) {
@@ -1405,7 +1403,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
ontology = tracker_ontologies_get_ontology_by_uri (manager->ontologies, subject);
if (ontology == NULL) {
g_critical ("%s: Unknown ontology %s", object_location, subject);
- goto out;
+ goto fail;
}
if (tracker_ontology_get_is_new (ontology) != in_update) {
@@ -1417,7 +1415,7 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
g_critical ("%s: error parsing nrl:lastModified: %s",
object_location, error->message);
g_error_free (error);
- goto out;
+ goto fail;
}
tracker_ontology_set_last_modified (ontology, g_date_time_to_unix (datetime));
@@ -1426,6 +1424,12 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager,
out:
g_free(object_location);
+ return;
+
+fail:
+ g_free(object_location);
+ if (loaded_successfully)
+ *loaded_successfully = FALSE;
}
@@ -1973,6 +1977,7 @@ load_ontology_file (TrackerDataManager *manager,
gboolean in_update,
GPtrArray *seen_classes,
GPtrArray *seen_properties,
+ guint *num_parsing_errors,
GError **error)
{
TrackerTurtleReader *reader;
@@ -1981,6 +1986,9 @@ load_ontology_file (TrackerDataManager *manager,
const gchar *subject, *predicate, *object;
goffset object_line_no, object_column_no;
+ if (num_parsing_errors)
+ *num_parsing_errors = 0;
+
reader = tracker_turtle_reader_new_for_file (file, &ttl_error);
if (ttl_error) {
@@ -1997,11 +2005,16 @@ load_ontology_file (TrackerDataManager *manager,
NULL, NULL, &object_line_no,
&object_column_no, &ttl_error)) {
GError *ontology_error = NULL;
+ gboolean loaded_successfully;
tracker_data_ontology_load_statement (manager, ontology_uri,
subject, predicate, object,
object_line_no, object_column_no, in_update,
- seen_classes, seen_properties, &ontology_error);
+ &loaded_successfully, seen_classes,
+ seen_properties, &ontology_error);
+
+ if (num_parsing_errors && !loaded_successfully)
+ (*num_parsing_errors)++;
if (ontology_error) {
g_propagate_error (error, ontology_error);
@@ -4076,6 +4089,7 @@ tracker_data_manager_initable_init (GInitable *initable,
if (is_create) {
TrackerOntology **ontologies;
guint n_ontologies, i;
+ guint num_parsing_errors = 0;
if (!manager->ontology_location) {
g_set_error (error,
@@ -4108,6 +4122,7 @@ tracker_data_manager_initable_init (GInitable *initable,
GError *ontology_error = NULL;
GFile *ontology_file = l->data;
gchar *uri = g_file_get_uri (ontology_file);
+ guint num_ontology_parsing_errors;
TRACKER_NOTE (ONTOLOGY_CHANGES, g_message ("Loading ontology %s", uri));
@@ -4115,6 +4130,7 @@ tracker_data_manager_initable_init (GInitable *initable,
FALSE,
NULL,
NULL,
+ &num_ontology_parsing_errors,
&ontology_error);
g_free (uri);
@@ -4122,6 +4138,17 @@ tracker_data_manager_initable_init (GInitable *initable,
g_propagate_error (error, ontology_error);
goto rollback_newly_created_db;
}
+
+ num_parsing_errors += num_ontology_parsing_errors;
+ }
+
+ if (num_parsing_errors) {
+ g_set_error (error,
+ TRACKER_SPARQL_ERROR,
+ TRACKER_SPARQL_ERROR_PARSE,
+ "The ontology files contain %u parsing error(s)",
+ num_parsing_errors);
+ goto rollback_newly_created_db;
}
check_properties_completeness (manager->ontologies, &internal_error);
@@ -4232,6 +4259,7 @@ tracker_data_manager_initable_init (GInitable *initable,
GPtrArray *seen_properties;
GError *n_error = NULL;
gboolean transaction_started = FALSE;
+ guint num_parsing_errors = 0;
seen_classes = g_ptr_array_new_with_free_func (g_object_unref);
seen_properties = g_ptr_array_new_with_free_func (g_object_unref);
@@ -4338,6 +4366,7 @@ tracker_data_manager_initable_init (GInitable *initable,
* modified in the latest version of the file, deal with changes. */
if (val != last_mod) {
gchar *uri = g_file_get_uri (ontology_file);
+ guint num_ontology_parsing_errors;
TRACKER_NOTE (ONTOLOGY_CHANGES, g_message ("Ontology file '%s' needs
update", uri));
g_free (uri);
@@ -4357,6 +4386,7 @@ tracker_data_manager_initable_init (GInitable *initable,
TRUE,
seen_classes,
seen_properties,
+ &num_ontology_parsing_errors,
&ontology_error);
if (ontology_error) {
@@ -4372,12 +4402,15 @@ tracker_data_manager_initable_init (GInitable *initable,
goto rollback_db_changes;
}
+ num_parsing_errors += num_ontology_parsing_errors;
+
to_reload = g_list_prepend (to_reload, l->data);
update_nao = TRUE;
}
} else {
GError *ontology_error = NULL;
gchar *uri = g_file_get_uri (ontology_file);
+ guint num_ontology_parsing_errors;
g_debug ("Ontology file '%s' got added", uri);
g_free (uri);
@@ -4397,6 +4430,7 @@ tracker_data_manager_initable_init (GInitable *initable,
TRUE,
seen_classes,
seen_properties,
+ &num_ontology_parsing_errors,
&ontology_error);
if (ontology_error) {
@@ -4412,10 +4446,7 @@ tracker_data_manager_initable_init (GInitable *initable,
goto rollback_db_changes;
}
- if (ontology_error) {
- g_critical ("Fatal error dealing with ontology changes: %s",
ontology_error->message);
- g_error_free (ontology_error);
- }
+ num_parsing_errors += num_ontology_parsing_errors;
to_reload = g_list_prepend (to_reload, l->data);
update_nao = TRUE;
@@ -4433,6 +4464,15 @@ tracker_data_manager_initable_init (GInitable *initable,
g_object_unref (ontology);
}
+ if (num_parsing_errors) {
+ g_set_error (error,
+ TRACKER_SPARQL_ERROR,
+ TRACKER_SPARQL_ERROR_PARSE,
+ "The ontology files contain %u parsing error(s)",
+ num_parsing_errors);
+ goto rollback_db_changes;
+ }
+
check_properties_completeness (manager->ontologies, &n_error);
if (n_error) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]