Empêche l'erreur de la demande indexéeDB d'annuler la transaction

Mon intention

Faites une boucle dans localStorage et placez les données dans IndexedDB. Si certaines erreurs connues se produisent, comme un ConstraintError lorsqu'une clé existe déjà, je souhaite ignorer ces erreurs spécifiques, de sorte que la transaction ne soit pas interrompue. Aborter la transaction est le comportement par défaut lorsqu'une demande déclenche une erreur.

Le problème

Je pensais que l'utilisation d' event.preventDefault() dans le gestionnaire de requêtes onerror empêcherait que cela ne se produise. Étonnamment, l'événement reste encore dans le gestionnaire d'erreurs de la transaction! Je peux voir cela en activant la journalisation (voir le code ci-dessous).

 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(); } }; } } 

Il semble que la sortie d'enregistrement du code que j'ai collé m'a trompé en pensant que la transaction a été interrompue, puisque le gestionnaire de transaction.onerror a été appelé. Ce que je n'ai pas enregistré, cependant, était de savoir si transaction.onabort était appelé … Il s'est avéré qu'un appel à event.preventDefault en fait était suffisant!

Ce qui m'a confondu, c'est que l'erreur s'est propagée au gestionnaire d'erreur de transaction. Cependant, la transaction n'a pas été interrompue! . Il a simplement fait exploser l'événement après avoir empêché l'action par défaut (annulation). Pour se débarrasser du message, je dois également appeler event.stopPropagation afin d'éviter que l'événement ne bouleverse le gestionnaire d'erreurs de la transaction. Notez que ceci n'est pas strictement nécessaire si vous avez besoin que la transaction ne soit pas annulée.

J'ai trouvé la réponse en creusant dans les documents W3C sur IDBRecust et IBTransaction.

Il est logique que la transaction soit erronée lorsque quelque chose ne va pas dans la transaction. Il existe des transactions à moyen, pour maintenir la base de données cohérente.

Dans votre cas, vérifiez d'abord si la clé existe. Si c'est le cas, ne faites rien dans l'autre cas, vous pouvez insérer les données.

Une autre solution ouvre une transaction pour chaque objet que vous souhaitez enregistrer …