Prevent IndexedDB request error from cancelling the transaction

做~自己de王妃 提交于 2019-12-21 20:12:42

问题


My intent

Loop through localStorage and put the data into IndexedDB. If certain known errors happen, such as a ConstraintError when a key already exists, I want to ignore those specific errors, so that the transaction is not aborted. Aborting the transaction is the default behaviour when a request triggers an error.

The problem

I thought that using event.preventDefault() in the requests onerror handler would prevent this from happening. Surprisingly, the event still surfaces in the transaction's error handler! I can see this happening by turning on logging (see the code below).

transaction.onerror = function (event) {
    log('IndexedDb.migrateLocalStorage -> transaction -> onerror', event.target.error.name);
};
transaction.oncomplete = function () {
    log('IndexedDb.migrateLocalStorage -> transaction -> oncomplete');
};

for (var key in $W.localStorage) {

    if ($W.localStorage.hasOwnProperty(key)) {
        value = $W.localStorage.getItem(key);
        request = objectStore.add(addQuotesIfNecessary(value), key);
        request.onerror = function (event) {
            var error = event.target.error;
            log('IndexedDb.migrateLocalStorage -> request -> onerror', error, error.name);

            // do nothing if the same key exists in indexeddb. it is likely newer
            if (error.name === 'ConstraintError') { event.preventDefault(); }
        };
    }
}

回答1:


It seems the logging output from the code I pasted tricked me into thinking that the transaction was aborted, since the transaction.onerror handler was called. What I did not log, though, was whether transaction.onabort was called ... It turned out that a call to event.preventDefault actually was enough!

What confused me was that the error propagated up to the transaction error handler. The transaction was not aborted, though!. It just bubbled up the event after preventing the default action (aborting). To get rid of the message I also need to call event.stopPropagation in order to prevent the event from bubbling up to the transaction's error handler. Note that this is not strictly necessary if you just need the transaction to not be cancelled.

I found the answer by digging around in the W3C docs on IDBRequst and IBTransaction.




回答2:


It is logical that the transaction is in error when something goes wrong inside the transaction. That is way transactions exist, to keep the database consistent.

In your case you should better first check if the key exists. If it does, do nothing in the other case you can insert the data.

An other solution is opening a transaction for every object you want to save....



来源:https://stackoverflow.com/questions/22831385/prevent-indexeddb-request-error-from-cancelling-the-transaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!