Fix bug 470394 - Guard all SQL transactions in case of database corruption. r=dbo
authorPhilipp Kewisch <mozilla@kewis.ch>
Sun, 21 Dec 2008 20:08:59 +0100
changeset 1475 260b5e14bef1cac4f8fb878b801eb327762473e5
parent 1474 2a4c4c1f0febe3fbf8cd2d4b708c9fa470b79e82
child 1476 71025c5f3967243d8543d31a731d09a1532cb366
push idunknown
push userunknown
push dateunknown
reviewersdbo
bugs470394
Fix bug 470394 - Guard all SQL transactions in case of database corruption. r=dbo
calendar/providers/storage/calStorageCalendar.js
--- a/calendar/providers/storage/calStorageCalendar.js
+++ b/calendar/providers/storage/calStorageCalendar.js
@@ -751,22 +751,27 @@ calStorageCalendar.prototype = {
             // first get non-recurring events that happen to fall within the range
             //
             sp = this.mSelectNonRecurringEventsByRange.params;
             sp.range_start = startTime;
             sp.range_end = endTime;
             sp.start_offset = aRangeStart ? aRangeStart.timezoneOffset * USECS_PER_SECOND : 0;
             sp.end_offset = aRangeEnd ? aRangeEnd.timezoneOffset * USECS_PER_SECOND : 0;
 
-            while (this.mSelectNonRecurringEventsByRange.step()) {
-                var row = this.mSelectNonRecurringEventsByRange.row;
-                var item = this.getEventFromRow(row, {});
-                resultItems.push(item);
+            try {
+                while (this.mSelectNonRecurringEventsByRange.step()) {
+                    let row = this.mSelectNonRecurringEventsByRange.row;
+                    resultItems.push(this.getEventFromRow(row, {}));
+                }
+            } catch (e) {
+                cal.ERROR("Error selecting non recurring events by range!\n" + e +
+                          "\nDB Error: " + this.mDB.lastErrorString);
+            } finally {
+                this.mSelectNonRecurringEventsByRange.reset();
             }
-            this.mSelectNonRecurringEventsByRange.reset();
 
             // process the non-recurring events:
             for each (var evitem in resultItems) {
                 count += handleResultItem(evitem, Components.interfaces.calIEvent);
                 if (checkCount()) {
                     return;
                 }
             }
@@ -787,21 +792,27 @@ calStorageCalendar.prototype = {
 
             // first get non-recurring todos that happen to fall within the range
             sp = this.mSelectNonRecurringTodosByRange.params;
             sp.range_start = startTime;
             sp.range_end = endTime;
             sp.start_offset = aRangeStart ? aRangeStart.timezoneOffset * USECS_PER_SECOND : 0;
             sp.end_offset = aRangeEnd ? aRangeEnd.timezoneOffset * USECS_PER_SECOND : 0;
 
-            while (this.mSelectNonRecurringTodosByRange.step()) {
-                var row = this.mSelectNonRecurringTodosByRange.row;
-                resultItems.push(this.getTodoFromRow(row, {}));
+            try {
+                while (this.mSelectNonRecurringTodosByRange.step()) {
+                    let row = this.mSelectNonRecurringTodosByRange.row;
+                    resultItems.push(this.getTodoFromRow(row, {}));
+                }
+            } catch (e) {
+                cal.ERROR("Error selecting non recurring todos by range!\n" + e +
+                          "\nDB Error: " + this.mDB.lastErrorString);
+            } finally {
+                this.mSelectNonRecurringTodosByRange.reset();
             }
-            this.mSelectNonRecurringTodosByRange.reset();
 
             // process the non-recurring todos:
             for each (var todoitem in resultItems) {
                 count += handleResultItem(todoitem, Components.interfaces.calITodo, checkCompleted);
                 if (checkCount()) {
                     return;
                 }
             }
@@ -867,32 +878,32 @@ calStorageCalendar.prototype = {
 
         try {
             selectSchemaVersion = createStatement(this.mDB, 
                                   "SELECT version FROM " +
                                   "cal_calendar_schema_version LIMIT 1");
             if (selectSchemaVersion.step()) {
                 version = selectSchemaVersion.row.version;
             }
-            selectSchemaVersion.reset();
 
             if (version !== null) {
                 // This is the only place to leave this function gracefully.
                 return version;
             }
         } catch (e) {
-            if (selectSchemaVersion) {
-                selectSchemaVersion.reset();
-            }
             dump ("++++++++++++ calStorageGetVersion() error: " +
                   this.mDB.lastErrorString + "\n");
             Components.utils.reportError("Error getting storage calendar " +
                                          "schema version! DB Error: " + 
                                          this.mDB.lastErrorString);
             throw e;
+        } finally {
+            if (selectSchemaVersion) {
+                selectSchemaVersion.reset();
+            }
         }
 
         throw "cal_calendar_schema_version SELECT returned no results";
     },
 
     upgradeDB: function (oldVersion) {
         // some common helpers
         function addColumn(db, tableName, colName, colType) {
@@ -1148,17 +1159,17 @@ calStorageCalendar.prototype = {
             try {
                 this.mDB.createTable("cal_attachments", sqlTables.cal_attachments);
 
                 // update schema
                 this.mDB.executeSimpleSQL("UPDATE cal_calendar_schema_version SET version = 11;");
                 this.mDB.commitTransaction();
                 oldVersion = 11;
             } catch (e) {
-                ERROR("Upgrade failed! DB Error: " + this.mDB.lastErrorString);
+                cal.ERROR("Upgrade failed! DB Error: " + this.mDB.lastErrorString);
                 this.mDB.rollbackTransaction();
                 throw e;
             }
         }
 
         if (oldVersion < 12) {
             this.mDB.beginTransaction();
             try {
@@ -1166,17 +1177,17 @@ calStorageCalendar.prototype = {
                 addColumn(this.mDB, "cal_attendees", "is_organizer", "BOOLEAN");
                 addColumn(this.mDB, "cal_attendees", "properties", "BLOB");
 
                 // update schema
                 this.mDB.executeSimpleSQL("UPDATE cal_calendar_schema_version SET version = 12;");
                 this.mDB.commitTransaction();
                 oldVersion = 12;
             } catch (e) {
-                ERROR("Upgrade failed! DB Error: " + this.mDB.lastErrorString);
+                cal.ERROR("Upgrade failed! DB Error: " + this.mDB.lastErrorString);
                 this.mDB.rollbackTransaction();
                 throw e;
             }
         }
 
         if (oldVersion < 13) {
             this.mDB.beginTransaction();
             try {
@@ -1220,47 +1231,47 @@ calStorageCalendar.prototype = {
                 this.mDB.executeSimpleSQL("CREATE INDEX IF NOT EXISTS" + 
                                           " idx_cal_properies_item_id" +
                                           " ON cal_properties(cal_id, item_id);");
 
                 this.mDB.executeSimpleSQL("UPDATE cal_calendar_schema_version SET version = 13;");
                 this.mDB.commitTransaction();
                 oldVersion = 13;
             } catch (e) {
-                ERROR("Upgrade failed! DB Error: " + this.mDB.lastErrorString);
+                cal.ERROR("Upgrade failed! DB Error: " + this.mDB.lastErrorString);
                 this.mDB.rollbackTransaction();
                 throw e;
             }
         }
 
         if (oldVersion < 14) {
             this.mDB.beginTransaction();
             try {
                 this.mDB.createTable("cal_relations", sqlTables.cal_relations);
                 // update schema
                 this.mDB.executeSimpleSQL("UPDATE cal_calendar_schema_version SET version = 14;");
                 this.mDB.commitTransaction();
                 oldVersion = 14;
             } catch (e) {
-                ERROR("Upgrade failed! DB Error: " + this.mDB.lastErrorString);
+                cal.ERROR("Upgrade failed! DB Error: " + this.mDB.lastErrorString);
                 this.mDB.rollbackTransaction();
                 throw e;
             }
         }
 
         if (oldVersion < 15) {
             this.mDB.beginTransaction();
             try {
                 addColumn(this.mDB, "cal_todos", "todo_stamp", "INTEGER");
                 // update schema
                 this.mDB.executeSimpleSQL("UPDATE cal_calendar_schema_version SET version = 15;");
                 this.mDB.commitTransaction();
                 oldVersion = 15;
             } catch (e) {
-                ERROR("Upgrade failed! DB Error: " + this.mDB.lastErrorString);
+                cal.ERROR("Upgrade failed! DB Error: " + this.mDB.lastErrorString);
                 this.mDB.rollbackTransaction();
                 throw e;
             }
         }
 
         if (oldVersion != this.DB_SCHEMA_VERSION) {
             dump ("#######!!!!! calStorageCalendar Schema Update failed -- db version: " + oldVersion + " this version: " + this.DB_SCHEMA_VERSION + "\n");
             throw Components.results.NS_ERROR_FAILURE;
@@ -1789,30 +1800,42 @@ calStorageCalendar.prototype = {
     assureRecurringItemCaches: function stor_assureRecurringItemCaches() {
         if (this.mRecItemCacheInited) {
             return;
         }
         // build up recurring event and todo cache, because we need that on every query:
         // for recurring items, we need to query database-wide.. yuck
 
         sp = this.mSelectEventsWithRecurrence.params;
-        while (this.mSelectEventsWithRecurrence.step()) {
-            var row = this.mSelectEventsWithRecurrence.row;
-            var item = this.getEventFromRow(row, {});
-            this.mRecEventCache[item.id] = item;
+        try {
+            while (this.mSelectEventsWithRecurrence.step()) {
+                var row = this.mSelectEventsWithRecurrence.row;
+                var item = this.getEventFromRow(row, {});
+                this.mRecEventCache[item.id] = item;
+            }
+        } catch (e) {
+            cal.ERROR("Error selecting events with recurrence!\n" + e +
+                      "\nDB Error: " + this.mDB.lastErrorString);
+        } finally {
+            this.mSelectEventsWithRecurrence.reset();
         }
-        this.mSelectEventsWithRecurrence.reset();
 
         sp = this.mSelectTodosWithRecurrence.params;
-        while (this.mSelectTodosWithRecurrence.step()) {
-            var row = this.mSelectTodosWithRecurrence.row;
-            var item = this.getTodoFromRow(row, {});
-            this.mRecTodoCache[item.id] = item;
+        try {
+            while (this.mSelectTodosWithRecurrence.step()) {
+                var row = this.mSelectTodosWithRecurrence.row;
+                var item = this.getTodoFromRow(row, {});
+                this.mRecTodoCache[item.id] = item;
+            }
+        } catch (e) {
+            cal.ERROR("Error selecting todos with recurrence!\n" + e +
+                      "\nDB Error: " + this.mDB.lastErrorString);
+        } finally {
+            this.mSelectTodosWithRecurrence.reset();
         }
-        this.mSelectTodosWithRecurrence.reset();
 
         this.mRecItemCacheInited = true;
     },
 
     // xxx todo: consider removing flags parameter
     getEventFromRow: function stor_getEventFromRow(row, flags, isException) {
         var item;
         if (!isException) { // only parent items are cached
@@ -1895,198 +1918,247 @@ calStorageCalendar.prototype = {
                 selectItem = this.mSelectAttendeesForItem;
             else {
                 selectItem = this.mSelectAttendeesForItemWithRecurrenceId;
                 this.setDateParamHelper(selectItem.params, "recurrence_id", item.recurrenceId);
             }
 
             selectItem.params.item_id = item.id;
 
-            while (selectItem.step()) {
-                var attendee = this.getAttendeeFromRow(selectItem.row);
-                if (attendee.isOrganizer) {
-                    item.organizer = attendee;
-                } else {
-                    item.addAttendee(attendee);
+            try {
+                while (selectItem.step()) {
+                    var attendee = this.getAttendeeFromRow(selectItem.row);
+                    if (attendee.isOrganizer) {
+                        item.organizer = attendee;
+                    } else {
+                        item.addAttendee(attendee);
+                    }
                 }
+            } catch (e) {
+                cal.ERROR("Error getting attendees for item '" +
+                          item.title + "' (" + item.id + ")!\n" + e +
+                          "\nDB Error: " + this.mDB.lastErrorString);
+            } finally {
+                selectItem.reset();
             }
-            selectItem.reset();
         }
 
         var row;
         if (flags & CAL_ITEM_FLAG_HAS_PROPERTIES) {
             var selectItem = null;
             if (item.recurrenceId == null)
                 selectItem = this.mSelectPropertiesForItem;
             else {
                 selectItem = this.mSelectPropertiesForItemWithRecurrenceId;
                 this.setDateParamHelper(selectItem.params, "recurrence_id", item.recurrenceId);
             }
                 
             selectItem.params.item_id = item.id;
             
-            while (selectItem.step()) {
-                row = selectItem.row;
-                var name = row.key;
-                switch (name) {
-                    case "DURATION":
-                        // for events DTEND/DUE is enforced by calEvent/calTodo, so suppress DURATION:
-                        break;
-                    case "CATEGORIES": {
-                        var cats = categoriesStringToArray(row.value);
-                        item.setCategories(cats.length, cats);
-                        break;
+            try {
+                while (selectItem.step()) {
+                    row = selectItem.row;
+                    var name = row.key;
+                    switch (name) {
+                        case "DURATION":
+                            // for events DTEND/DUE is enforced by calEvent/calTodo, so suppress DURATION:
+                            break;
+                        case "CATEGORIES": {
+                            var cats = categoriesStringToArray(row.value);
+                            item.setCategories(cats.length, cats);
+                            break;
+                        }
+                        default:
+                            item.setProperty(name, row.value);
+                            break;
                     }
-                    default:
-                        item.setProperty(name, row.value);
-                        break;
                 }
+            } catch (e) {
+                cal.ERROR("Error getting extra properties for item '" +
+                          item.title + "' (" + item.id + ")!\n" + e +
+                          "\nDB Error: " + this.mDB.lastErrorString);
+            } finally {
+                selectItem.reset();
             }
-            selectItem.reset();
         }
 
         var i;
         if (flags & CAL_ITEM_FLAG_HAS_RECURRENCE) {
             if (item.recurrenceId)
                 throw Components.results.NS_ERROR_UNEXPECTED;
 
             var rec = null;
 
             this.mSelectRecurrenceForItem.params.item_id = item.id;
-            while (this.mSelectRecurrenceForItem.step()) {
-                row = this.mSelectRecurrenceForItem.row;
-
-                var ritem = null;
-
-                if (row.recur_type == null ||
-                    row.recur_type == "x-dateset")
-                {
-                    ritem = new CalRecurrenceDateSet();
-
-                    var dates = row.dates.split(",");
-                    for (i = 0; i < dates.length; i++) {
-                        var date = textToDate(dates[i]);
-                        ritem.addDate(date);
-                    }
-                } else if (row.recur_type == "x-date") {
-                    ritem = new CalRecurrenceDate();
-                    var d = row.dates;
-                    ritem.date = textToDate(d);
-                } else {
-                    ritem = new CalRecurrenceRule();
-
-                    ritem.type = row.recur_type;
-                    if (row.count) {
+            try {
+                while (this.mSelectRecurrenceForItem.step()) {
+                    row = this.mSelectRecurrenceForItem.row;
+
+                    var ritem = null;
+
+                    if (row.recur_type == null ||
+                        row.recur_type == "x-dateset")
+                    {
+                        ritem = new CalRecurrenceDateSet();
+
+                        var dates = row.dates.split(",");
+                        for (i = 0; i < dates.length; i++) {
+                            var date = textToDate(dates[i]);
+                            ritem.addDate(date);
+                        }
+                    } else if (row.recur_type == "x-date") {
+                        ritem = new CalRecurrenceDate();
+                        var d = row.dates;
+                        ritem.date = textToDate(d);
+                    } else {
+                        ritem = new CalRecurrenceRule();
+
+                        ritem.type = row.recur_type;
+                        if (row.count) {
+                            try {
+                                ritem.count = row.count;
+                            } catch(exc) {
+                            }
+                        } else {
+                            if (row.end_date)
+                                ritem.endDate = newDateTime(row.end_date);
+                            else
+                                ritem.endDate = null;
+                        }
                         try {
-                            ritem.count = row.count;
+                            ritem.interval = row.interval;
                         } catch(exc) {
                         }
-                    } else {
-                        if (row.end_date)
-                            ritem.endDate = newDateTime(row.end_date);
-                        else
-                            ritem.endDate = null;
-                    }
-                    try {
-                        ritem.interval = row.interval;
-                    } catch(exc) {
-                    }
-
-                    var rtypes = ["second",
-                                  "minute",
-                                  "hour",
-                                  "day",
-                                  "monthday",
-                                  "yearday",
-                                  "weekno",
-                                  "month",
-                                  "setpos"];
-
-                    for (i = 0; i < rtypes.length; i++) {
-                        var comp = "BY" + rtypes[i].toUpperCase();
-                        if (row[rtypes[i]]) {
-                            var rstr = row[rtypes[i]].toString().split(",");
-                            var rarray = [];
-                            for (var j = 0; j < rstr.length; j++) {
-                                rarray[j] = parseInt(rstr[j]);
+
+                        var rtypes = ["second",
+                                      "minute",
+                                      "hour",
+                                      "day",
+                                      "monthday",
+                                      "yearday",
+                                      "weekno",
+                                      "month",
+                                      "setpos"];
+
+                        for (i = 0; i < rtypes.length; i++) {
+                            var comp = "BY" + rtypes[i].toUpperCase();
+                            if (row[rtypes[i]]) {
+                                var rstr = row[rtypes[i]].toString().split(",");
+                                var rarray = [];
+                                for (var j = 0; j < rstr.length; j++) {
+                                    rarray[j] = parseInt(rstr[j]);
+                                }
+
+                                ritem.setComponent (comp, rarray.length, rarray);
                             }
-
-                            ritem.setComponent (comp, rarray.length, rarray);
                         }
                     }
+
+                    if (row.is_negative)
+                        ritem.isNegative = true;
+                    if (rec == null) {
+                        rec = new CalRecurrenceInfo();
+                        rec.item = item;
+                    }
+                    rec.appendRecurrenceItem(ritem);
                 }
-
-                if (row.is_negative)
-                    ritem.isNegative = true;
-                if (rec == null) {
-                    rec = new CalRecurrenceInfo();
-                    rec.item = item;
-                }
-                rec.appendRecurrenceItem(ritem);
+            } catch (e) {
+                cal.ERROR("Error getting recurrence for item '" +
+                          item.title + "' (" + item.id + ")!\n" + e +
+                          "\nDB Error: " + this.mDB.lastErrorString);
+            } finally {
+                this.mSelectRecurrenceForItem.reset();
             }
 
             if (rec == null) {
                 dump ("XXXX Expected to find recurrence, but got no items!\n");
             }
             item.recurrenceInfo = rec;
 
-            this.mSelectRecurrenceForItem.reset();
         }
 
         if (flags & CAL_ITEM_FLAG_HAS_EXCEPTIONS) {
             // it's safe that we don't run into this branch again for exceptions
             // (getAdditionalDataForItem->get[Event|Todo]FromRow->getAdditionalDataForItem):
             // every excepton has a recurrenceId and isn't flagged as CAL_ITEM_FLAG_HAS_EXCEPTIONS
             if (item.recurrenceId)
                 throw Components.results.NS_ERROR_UNEXPECTED;
 
             var rec = item.recurrenceInfo;
 
             if (isEvent(item)) {
                 this.mSelectEventExceptions.params.id = item.id;
-                while (this.mSelectEventExceptions.step()) {
-                    var row = this.mSelectEventExceptions.row;
-                    var exc = this.getEventFromRow(row, {}, true /*isException*/);
-                    rec.modifyException(exc, true);
+                try {
+                    while (this.mSelectEventExceptions.step()) {
+                        var row = this.mSelectEventExceptions.row;
+                        var exc = this.getEventFromRow(row, {}, true /*isException*/);
+                        rec.modifyException(exc, true);
+                    }
+                } catch (e) {
+                    cal.ERROR("Error getting exceptions for event '" +
+                              item.title + "' (" + item.id + ")!\n" + e +
+                              "\nDB Error: " + this.mDB.lastErrorString);
+                } finally {
+                    this.mSelectEventExceptions.reset();
                 }
-                this.mSelectEventExceptions.reset();
             } else if (isToDo(item)) {
                 this.mSelectTodoExceptions.params.id = item.id;
-                while (this.mSelectTodoExceptions.step()) {
-                    var row = this.mSelectTodoExceptions.row;
-                    var exc = this.getTodoFromRow(row, {}, true /*isException*/);
-                    rec.modifyException(exc, true);
+                try {
+                    while (this.mSelectTodoExceptions.step()) {
+                        var row = this.mSelectTodoExceptions.row;
+                        var exc = this.getTodoFromRow(row, {}, true /*isException*/);
+                        rec.modifyException(exc, true);
+                    }
+                } catch (e) {
+                    cal.ERROR("Error getting exceptions for task '" +
+                              item.title + "' (" + item.id + ")!\n" + e +
+                              "\nDB Error: " + this.mDB.lastErrorString);
+                } finally {
+                    this.mSelectTodoExceptions.reset();
                 }
-                this.mSelectTodoExceptions.reset();
             } else {
                 throw Components.results.NS_ERROR_UNEXPECTED;
             }
         }
 
         if (flags & CAL_ITEM_FLAG_HAS_ATTACHMENTS) {
             var selectAttachment = this.mSelectAttachmentsForItem;
             selectAttachment.params.item_id = item.id;
 
-            while (selectAttachment.step()) {
-                var row = selectAttachment.row;
-                var attachment = this.getAttachmentFromRow(row);
-                item.addAttachment(attachment);
+            try { 
+                while (selectAttachment.step()) {
+                    var row = selectAttachment.row;
+                    var attachment = this.getAttachmentFromRow(row);
+                    item.addAttachment(attachment);
+                }
+            } catch (e) {
+                cal.ERROR("Error getting attachments for item '" +
+                          item.title + "' (" + item.id + ")!\n" + e +
+                          "\nDB Error: " + this.mDB.lastErrorString);
+            } finally {
+                selectAttachment.reset();
             }
-            selectAttachment.reset();
         }
 
         if (flags & CAL_ITEM_FLAG_HAS_RELATIONS) {
             var selectRelation = this.mSelectRelationsForItem;
             selectRelation.params.item_id = item.id;
-            while (selectRelation.step()) {
-                var row = selectRelation.row;
-                var relation = this.getRelationFromRow(row);
-                item.addRelation(relation);
+            try {
+                while (selectRelation.step()) {
+                    var row = selectRelation.row;
+                    var relation = this.getRelationFromRow(row);
+                    item.addRelation(relation);
+                }
+            } catch (e) {
+                cal.ERROR("Error getting relations for item '" +
+                          item.title + "' (" + item.id + ")!\n" + e +
+                          "\nDB Error: " + this.mDB.lastErrorString);
+            } finally {
+                selectRelation.reset();
             }
-            selectRelation.reset();
         }
 
         // Restore the saved modification time
         item.setProperty("LAST-MODIFIED", savedLastModifiedTime);
     },
 
     getAttendeeFromRow: function (row) {
         var a = CalAttendee();
@@ -2147,26 +2219,40 @@ calStorageCalendar.prototype = {
             return item;
         }
 
         // not cached; need to read from the db
         var flags = {};
 
         // try events first
         this.mSelectEvent.params.id = aID;
-        if (this.mSelectEvent.step())
-            item = this.getEventFromRow(this.mSelectEvent.row, flags);
-        this.mSelectEvent.reset();
+        try {
+            if (this.mSelectEvent.step()) {
+                item = this.getEventFromRow(this.mSelectEvent.row, flags);
+            }
+        } catch (e) {
+            cal.ERROR("Error selecting item by id " + aID + "!\n" + e +
+                      "\nDB Error: " + this.mDB.lastErrorString);
+        } finally {
+            this.mSelectEvent.reset();
+        }
 
         // try todo if event fails
         if (!item) {
             this.mSelectTodo.params.id = aID;
-            if (this.mSelectTodo.step())
-                item = this.getTodoFromRow(this.mSelectTodo.row, flags);
-            this.mSelectTodo.reset();
+            try {
+                if (this.mSelectTodo.step()) {
+                    item = this.getTodoFromRow(this.mSelectTodo.row, flags);
+                }
+            } catch (e) {
+                cal.ERROR("Error selecting item by id " + aID + "!\n" + e +
+                          "\nDB Error: " + this.mDB.lastErrorString);
+            } finally {
+                this.mSelectTodo.reset();
+            }
         }
 
         return item;
     },
 
     //
     // database writing functions
     //
@@ -2542,17 +2628,17 @@ calStorageCalendar.prototype = {
         }
         if (gTransCount[uriKey]++ == 0) {
             this.mDB.beginTransaction();
         }
     },
     releaseTransaction: function stor_releaseTransaction(err) {
         var uriKey = this.uri.spec;
         if (err) {
-            ERROR("DB error: " + this.mDB.lastErrorString + "\nexc: " + err);
+            cal.ERROR("DB error: " + this.mDB.lastErrorString + "\nexc: " + err);
             gTransErr[uriKey] = exc;
         }
 
         if (gTransCount[uriKey] > 0) {
             if (--gTransCount[uriKey] == 0) {
                 if (gTransErr[uriKey]) {
                     this.mDB.rollbackTransaction();
                     delete gTransErr[uriKey];
@@ -2596,23 +2682,26 @@ calStorageCalendar.prototype = {
         this.mInsertMetaData.reset();
     },
 
     deleteMetaData: function stor_deleteMetaData(id) {
         this.mDeleteMetaData(id);
     },
 
     getMetaData: function stor_getMetaData(id) {
-        var query = this.mSelectMetaData;
+        let query = this.mSelectMetaData;
         query.params.item_id = id;
-        var value = null;
+        let value = null;
         try {
             if (query.step()) {
                 value = query.row.value;
             }
+        } catch (e) {
+            cal.ERROR("Error getting metadata for id " + id + "!\n" + e +
+                  "\nDB Error: " + this.mDB.lastErrorString);
         } finally {
             query.reset();
         }
         return value;
     },
 
     getAllMetaData: function stor_getAllMetaData(out_count,
                                                  out_ids,
@@ -2620,16 +2709,19 @@ calStorageCalendar.prototype = {
         var query = this.mSelectAllMetaData;
         var ids = [];
         var values = [];
         try {
             while (query.step()) {
                 ids.push(query.row.item_id);
                 values.push(query.row.value);
             }
+        } catch (e) {
+            cal.ERROR("Error getting all metadata!\n" + e +
+                      "\nDB Error: " + this.mDB.lastErrorString);
         } finally {
             query.reset();
         }
         out_count.value = ids.length;
         out_ids.value = ids;
         out_values.value = values;
     }
 };