Catching errors and rollbacks in indexedDBJavascript: Creating Functions in a For LoopAvoiding a ConstraintError when updating objects in indexedDBPrevent IndexedDB request error from cancelling the transactionIndexedDB: upgrade with promises?Conflicting purposes of IndexedDB transactionsproperly initializing an IndexedDB object storeBased on the IndexedDB spec, why do open database connections get closed on indexedDB.deleteDatabase calls?Phonegap IndexedDb not commiting data in Windows Phone 10 on larger databasesBrowser window close or tab close, get data from indexedDb and sent it to serverIndexedDB w/ two transactions: 1 read then 1 updateIndexedDB transaction error bubbles to db.onerror event of open request but displays uncaught exception error
Employer demanding to see degree after poor code review
Is the Starlink array really visible from Earth?
Employer asking for online access to bank account - Is this a scam?
The art of clickbait captions
Would Brexit have gone ahead by now if Gina Miller had not forced the Government to involve Parliament?
Count rotary dial pulses in a phone number (including letters)
Is CD audio quality good enough?
What does this symbol on the box of power supply mean?
Where is the logic in castrating fighters?
Were pens caps holes designed to prevent death by suffocation if swallowed?
Reduction from Exact Cover to Fixed Exact Cover
How to use " shadow " in pstricks?
Compactness of finite sets
Would jet fuel for an F-16 or F-35 be producible during WW2?
Is "cool" appropriate or offensive to use in IMs?
What are these arcade games in Ghostbusters 1984?
What is the object moving across the ceiling in this stock footage?
Why is this Simple Puzzle impossible to solve?
What does the view outside my ship traveling at light speed look like?
Simple function that simulates survey results based on sample size and probability
Make 24 using exactly three 3s
What to do when you've set the wrong ISO for your film?
Are these reasonable traits for someone with autism?
At what point in European history could a government build a printing press given a basic description?
Catching errors and rollbacks in indexedDB
Javascript: Creating Functions in a For LoopAvoiding a ConstraintError when updating objects in indexedDBPrevent IndexedDB request error from cancelling the transactionIndexedDB: upgrade with promises?Conflicting purposes of IndexedDB transactionsproperly initializing an IndexedDB object storeBased on the IndexedDB spec, why do open database connections get closed on indexedDB.deleteDatabase calls?Phonegap IndexedDb not commiting data in Windows Phone 10 on larger databasesBrowser window close or tab close, get data from indexedDb and sent it to serverIndexedDB w/ two transactions: 1 read then 1 updateIndexedDB transaction error bubbles to db.onerror event of open request but displays uncaught exception error
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I must be missing something very fundamental here and would appreciate any direction you may be able to provide. Thank you.
The following code is something that I thought was working when the commented out try-catch with the abort transaction in the catch was active. The abort transaction was triggering a req.onerror on every previous successful req, each of which in turn was triggering transaction.onerror and a too-much-recursion error. I worked that out and, not knowing much, thought everything was working fine such that individual request errors were triggering req.onerror and rollingback the transaction. However, it appears that it was only the abort statement in the catch that set that off. I was testing the error scenarios by sending bad data that couldn't be parsed as a JSON string.
But, now, that I'm using the same code in a scenario without the need for the try-catch and subsequent abort, I can't get the req.onerror to fire and don't understand why.
Argument o passed to DB_pop is an object containing the name of the object store, an array of data objects, and a string for 'add' or 'put'. I purposely pass one good data object and one with a null key, as seen in the first code statement below. The good one gets written, the bad one does not. The req.onerror and transaction.onerror do not fire. Only the transaction.oncomplete fires. Also, just one req.onsuccess fires. I conclude this because of what gets written to console log.
The then statement connected to the promise that invokes the DB_pop function, runs the reject function. The rollback function runs and the closing then that cleans up the variables to protect against memory leaks runs. I don't understand this either because if only the transaction.oncomplete is being triggered, it should resolve instead of reject.
Why doesn't a req.onerror fire for the second data object and cause the transaction to rollback and remove the first data object written?
I tried making req an array, and also removing the d loop and passing a single data object with a null key and neither onerror event fires.
I did notice that if an error is fabricated as an add to the database on an existing key, then all the error events fire, even up to the general error event set up in the database open/create. It seems that a null key in a put doesn't trigger an error as expected and rollback.
p = DB_pop( 'os' : 'topics', 'data' : [ 'key' : 0, 'gap' : T.gap, 'max' : T.max, 'selKey' : key , 'key' : null, 'title' : t, 'created' : d, 'edited' : d ], 'op' : 'put' );
p.then( () => T.title = t; , rollback ).then( () => evt = key = t = T = d = p = m = null; console.log('cleaned up'); );
function DB_pop( o ) // ( os, data, op )
return new Promise( ( resolve, reject ) =>
if ( !DB_open.base ) reject( 'Failed to populate database ' + DB_open.title + ' because the database is closed or does not exist.' );
let t = DB_open.base.transaction( [ o.os ], 'readwrite' ),
s = t.objectStore( o.os ),
req, d;
DB_pop.error = false;
function free_RAM()
t = s = req = d = null;
// close free_RAM
t.oncomplete = ( e ) =>
console.log('trans complete');
resolve();
free_RAM();
e = null;
; // close t.oncomplete
t.onerror = ( e ) =>
//e.stopPropagation(); // Stop propagation up to the database error level in the database open block.
DB_pop.error = true;
reject(e);
console.log( 'Transaction error : ' + e.target.error );
free_RAM();
e = null;
; // close t.onerror
t.onabort = ( e ) =>
console.log( 'Transaction aborted : ' + e.target.error );
free_RAM();
e = null;
; // close t.onabort
for ( d of o.data )
// try
// let q = JSON.parse( 'x' : d, 'y' : 3 );
// catch(e)
// t.abort(); error = true; break; //?????????? Test what takes place if the try fails.
req = s[ o.op ]( d ); // o.op is either 'add' or 'put'.
req.k = d.key;
req.n = d.nbr;
req.onsuccess = function( e )
if ( !DB_pop.error )
console.log( 'Success at k = ' + this.k + '.' );
; // end if
; // close req.onsuccess
req.onerror = function( e )
/*
When a transaction is rolled back/aborted, every request's error event is fired and propagates up to transaction.onerror and causes a "too much recursion" error.
Thus, let it propagate once and, within transaction.onerror, set error to true.
*/
console.log( 'Request.onerror fired. Error = ' + e.target.error + ' k = ' + this.k + ', n = ' + this.n );
if ( DB_pop.error )
e.stopPropagation();
console.log( 'Stopping propagation' );
; // end if
; // close req.onerror
; // next d
); // close promise
// close DB_pop
indexeddb
add a comment |
I must be missing something very fundamental here and would appreciate any direction you may be able to provide. Thank you.
The following code is something that I thought was working when the commented out try-catch with the abort transaction in the catch was active. The abort transaction was triggering a req.onerror on every previous successful req, each of which in turn was triggering transaction.onerror and a too-much-recursion error. I worked that out and, not knowing much, thought everything was working fine such that individual request errors were triggering req.onerror and rollingback the transaction. However, it appears that it was only the abort statement in the catch that set that off. I was testing the error scenarios by sending bad data that couldn't be parsed as a JSON string.
But, now, that I'm using the same code in a scenario without the need for the try-catch and subsequent abort, I can't get the req.onerror to fire and don't understand why.
Argument o passed to DB_pop is an object containing the name of the object store, an array of data objects, and a string for 'add' or 'put'. I purposely pass one good data object and one with a null key, as seen in the first code statement below. The good one gets written, the bad one does not. The req.onerror and transaction.onerror do not fire. Only the transaction.oncomplete fires. Also, just one req.onsuccess fires. I conclude this because of what gets written to console log.
The then statement connected to the promise that invokes the DB_pop function, runs the reject function. The rollback function runs and the closing then that cleans up the variables to protect against memory leaks runs. I don't understand this either because if only the transaction.oncomplete is being triggered, it should resolve instead of reject.
Why doesn't a req.onerror fire for the second data object and cause the transaction to rollback and remove the first data object written?
I tried making req an array, and also removing the d loop and passing a single data object with a null key and neither onerror event fires.
I did notice that if an error is fabricated as an add to the database on an existing key, then all the error events fire, even up to the general error event set up in the database open/create. It seems that a null key in a put doesn't trigger an error as expected and rollback.
p = DB_pop( 'os' : 'topics', 'data' : [ 'key' : 0, 'gap' : T.gap, 'max' : T.max, 'selKey' : key , 'key' : null, 'title' : t, 'created' : d, 'edited' : d ], 'op' : 'put' );
p.then( () => T.title = t; , rollback ).then( () => evt = key = t = T = d = p = m = null; console.log('cleaned up'); );
function DB_pop( o ) // ( os, data, op )
return new Promise( ( resolve, reject ) =>
if ( !DB_open.base ) reject( 'Failed to populate database ' + DB_open.title + ' because the database is closed or does not exist.' );
let t = DB_open.base.transaction( [ o.os ], 'readwrite' ),
s = t.objectStore( o.os ),
req, d;
DB_pop.error = false;
function free_RAM()
t = s = req = d = null;
// close free_RAM
t.oncomplete = ( e ) =>
console.log('trans complete');
resolve();
free_RAM();
e = null;
; // close t.oncomplete
t.onerror = ( e ) =>
//e.stopPropagation(); // Stop propagation up to the database error level in the database open block.
DB_pop.error = true;
reject(e);
console.log( 'Transaction error : ' + e.target.error );
free_RAM();
e = null;
; // close t.onerror
t.onabort = ( e ) =>
console.log( 'Transaction aborted : ' + e.target.error );
free_RAM();
e = null;
; // close t.onabort
for ( d of o.data )
// try
// let q = JSON.parse( 'x' : d, 'y' : 3 );
// catch(e)
// t.abort(); error = true; break; //?????????? Test what takes place if the try fails.
req = s[ o.op ]( d ); // o.op is either 'add' or 'put'.
req.k = d.key;
req.n = d.nbr;
req.onsuccess = function( e )
if ( !DB_pop.error )
console.log( 'Success at k = ' + this.k + '.' );
; // end if
; // close req.onsuccess
req.onerror = function( e )
/*
When a transaction is rolled back/aborted, every request's error event is fired and propagates up to transaction.onerror and causes a "too much recursion" error.
Thus, let it propagate once and, within transaction.onerror, set error to true.
*/
console.log( 'Request.onerror fired. Error = ' + e.target.error + ' k = ' + this.k + ', n = ' + this.n );
if ( DB_pop.error )
e.stopPropagation();
console.log( 'Stopping propagation' );
; // end if
; // close req.onerror
; // next d
); // close promise
// close DB_pop
indexeddb
Perhaps try printing the reason in your reject callback:p.then(() => /* fulfilled */ , (reason) -> console.log(reason)). An exception in the executor function would show up here.
– jspcal
Mar 24 at 6:10
Thanks for responding. It does print a reason which is " DataError: Data provided to an operation does not meet requirements." I assume that is because the key is null. The problem is that, even with this error response, the transaction completes without event error at any level, but it only partially completes when it should roll back. It appears to work properly for an add attempt to an existing key, as I added to my question afterward, but not a null key in a put attempt.
– Gary
Mar 24 at 6:16
add a comment |
I must be missing something very fundamental here and would appreciate any direction you may be able to provide. Thank you.
The following code is something that I thought was working when the commented out try-catch with the abort transaction in the catch was active. The abort transaction was triggering a req.onerror on every previous successful req, each of which in turn was triggering transaction.onerror and a too-much-recursion error. I worked that out and, not knowing much, thought everything was working fine such that individual request errors were triggering req.onerror and rollingback the transaction. However, it appears that it was only the abort statement in the catch that set that off. I was testing the error scenarios by sending bad data that couldn't be parsed as a JSON string.
But, now, that I'm using the same code in a scenario without the need for the try-catch and subsequent abort, I can't get the req.onerror to fire and don't understand why.
Argument o passed to DB_pop is an object containing the name of the object store, an array of data objects, and a string for 'add' or 'put'. I purposely pass one good data object and one with a null key, as seen in the first code statement below. The good one gets written, the bad one does not. The req.onerror and transaction.onerror do not fire. Only the transaction.oncomplete fires. Also, just one req.onsuccess fires. I conclude this because of what gets written to console log.
The then statement connected to the promise that invokes the DB_pop function, runs the reject function. The rollback function runs and the closing then that cleans up the variables to protect against memory leaks runs. I don't understand this either because if only the transaction.oncomplete is being triggered, it should resolve instead of reject.
Why doesn't a req.onerror fire for the second data object and cause the transaction to rollback and remove the first data object written?
I tried making req an array, and also removing the d loop and passing a single data object with a null key and neither onerror event fires.
I did notice that if an error is fabricated as an add to the database on an existing key, then all the error events fire, even up to the general error event set up in the database open/create. It seems that a null key in a put doesn't trigger an error as expected and rollback.
p = DB_pop( 'os' : 'topics', 'data' : [ 'key' : 0, 'gap' : T.gap, 'max' : T.max, 'selKey' : key , 'key' : null, 'title' : t, 'created' : d, 'edited' : d ], 'op' : 'put' );
p.then( () => T.title = t; , rollback ).then( () => evt = key = t = T = d = p = m = null; console.log('cleaned up'); );
function DB_pop( o ) // ( os, data, op )
return new Promise( ( resolve, reject ) =>
if ( !DB_open.base ) reject( 'Failed to populate database ' + DB_open.title + ' because the database is closed or does not exist.' );
let t = DB_open.base.transaction( [ o.os ], 'readwrite' ),
s = t.objectStore( o.os ),
req, d;
DB_pop.error = false;
function free_RAM()
t = s = req = d = null;
// close free_RAM
t.oncomplete = ( e ) =>
console.log('trans complete');
resolve();
free_RAM();
e = null;
; // close t.oncomplete
t.onerror = ( e ) =>
//e.stopPropagation(); // Stop propagation up to the database error level in the database open block.
DB_pop.error = true;
reject(e);
console.log( 'Transaction error : ' + e.target.error );
free_RAM();
e = null;
; // close t.onerror
t.onabort = ( e ) =>
console.log( 'Transaction aborted : ' + e.target.error );
free_RAM();
e = null;
; // close t.onabort
for ( d of o.data )
// try
// let q = JSON.parse( 'x' : d, 'y' : 3 );
// catch(e)
// t.abort(); error = true; break; //?????????? Test what takes place if the try fails.
req = s[ o.op ]( d ); // o.op is either 'add' or 'put'.
req.k = d.key;
req.n = d.nbr;
req.onsuccess = function( e )
if ( !DB_pop.error )
console.log( 'Success at k = ' + this.k + '.' );
; // end if
; // close req.onsuccess
req.onerror = function( e )
/*
When a transaction is rolled back/aborted, every request's error event is fired and propagates up to transaction.onerror and causes a "too much recursion" error.
Thus, let it propagate once and, within transaction.onerror, set error to true.
*/
console.log( 'Request.onerror fired. Error = ' + e.target.error + ' k = ' + this.k + ', n = ' + this.n );
if ( DB_pop.error )
e.stopPropagation();
console.log( 'Stopping propagation' );
; // end if
; // close req.onerror
; // next d
); // close promise
// close DB_pop
indexeddb
I must be missing something very fundamental here and would appreciate any direction you may be able to provide. Thank you.
The following code is something that I thought was working when the commented out try-catch with the abort transaction in the catch was active. The abort transaction was triggering a req.onerror on every previous successful req, each of which in turn was triggering transaction.onerror and a too-much-recursion error. I worked that out and, not knowing much, thought everything was working fine such that individual request errors were triggering req.onerror and rollingback the transaction. However, it appears that it was only the abort statement in the catch that set that off. I was testing the error scenarios by sending bad data that couldn't be parsed as a JSON string.
But, now, that I'm using the same code in a scenario without the need for the try-catch and subsequent abort, I can't get the req.onerror to fire and don't understand why.
Argument o passed to DB_pop is an object containing the name of the object store, an array of data objects, and a string for 'add' or 'put'. I purposely pass one good data object and one with a null key, as seen in the first code statement below. The good one gets written, the bad one does not. The req.onerror and transaction.onerror do not fire. Only the transaction.oncomplete fires. Also, just one req.onsuccess fires. I conclude this because of what gets written to console log.
The then statement connected to the promise that invokes the DB_pop function, runs the reject function. The rollback function runs and the closing then that cleans up the variables to protect against memory leaks runs. I don't understand this either because if only the transaction.oncomplete is being triggered, it should resolve instead of reject.
Why doesn't a req.onerror fire for the second data object and cause the transaction to rollback and remove the first data object written?
I tried making req an array, and also removing the d loop and passing a single data object with a null key and neither onerror event fires.
I did notice that if an error is fabricated as an add to the database on an existing key, then all the error events fire, even up to the general error event set up in the database open/create. It seems that a null key in a put doesn't trigger an error as expected and rollback.
p = DB_pop( 'os' : 'topics', 'data' : [ 'key' : 0, 'gap' : T.gap, 'max' : T.max, 'selKey' : key , 'key' : null, 'title' : t, 'created' : d, 'edited' : d ], 'op' : 'put' );
p.then( () => T.title = t; , rollback ).then( () => evt = key = t = T = d = p = m = null; console.log('cleaned up'); );
function DB_pop( o ) // ( os, data, op )
return new Promise( ( resolve, reject ) =>
if ( !DB_open.base ) reject( 'Failed to populate database ' + DB_open.title + ' because the database is closed or does not exist.' );
let t = DB_open.base.transaction( [ o.os ], 'readwrite' ),
s = t.objectStore( o.os ),
req, d;
DB_pop.error = false;
function free_RAM()
t = s = req = d = null;
// close free_RAM
t.oncomplete = ( e ) =>
console.log('trans complete');
resolve();
free_RAM();
e = null;
; // close t.oncomplete
t.onerror = ( e ) =>
//e.stopPropagation(); // Stop propagation up to the database error level in the database open block.
DB_pop.error = true;
reject(e);
console.log( 'Transaction error : ' + e.target.error );
free_RAM();
e = null;
; // close t.onerror
t.onabort = ( e ) =>
console.log( 'Transaction aborted : ' + e.target.error );
free_RAM();
e = null;
; // close t.onabort
for ( d of o.data )
// try
// let q = JSON.parse( 'x' : d, 'y' : 3 );
// catch(e)
// t.abort(); error = true; break; //?????????? Test what takes place if the try fails.
req = s[ o.op ]( d ); // o.op is either 'add' or 'put'.
req.k = d.key;
req.n = d.nbr;
req.onsuccess = function( e )
if ( !DB_pop.error )
console.log( 'Success at k = ' + this.k + '.' );
; // end if
; // close req.onsuccess
req.onerror = function( e )
/*
When a transaction is rolled back/aborted, every request's error event is fired and propagates up to transaction.onerror and causes a "too much recursion" error.
Thus, let it propagate once and, within transaction.onerror, set error to true.
*/
console.log( 'Request.onerror fired. Error = ' + e.target.error + ' k = ' + this.k + ', n = ' + this.n );
if ( DB_pop.error )
e.stopPropagation();
console.log( 'Stopping propagation' );
; // end if
; // close req.onerror
; // next d
); // close promise
// close DB_pop
indexeddb
indexeddb
edited Mar 24 at 5:58
Gary
asked Mar 24 at 5:20
GaryGary
25712
25712
Perhaps try printing the reason in your reject callback:p.then(() => /* fulfilled */ , (reason) -> console.log(reason)). An exception in the executor function would show up here.
– jspcal
Mar 24 at 6:10
Thanks for responding. It does print a reason which is " DataError: Data provided to an operation does not meet requirements." I assume that is because the key is null. The problem is that, even with this error response, the transaction completes without event error at any level, but it only partially completes when it should roll back. It appears to work properly for an add attempt to an existing key, as I added to my question afterward, but not a null key in a put attempt.
– Gary
Mar 24 at 6:16
add a comment |
Perhaps try printing the reason in your reject callback:p.then(() => /* fulfilled */ , (reason) -> console.log(reason)). An exception in the executor function would show up here.
– jspcal
Mar 24 at 6:10
Thanks for responding. It does print a reason which is " DataError: Data provided to an operation does not meet requirements." I assume that is because the key is null. The problem is that, even with this error response, the transaction completes without event error at any level, but it only partially completes when it should roll back. It appears to work properly for an add attempt to an existing key, as I added to my question afterward, but not a null key in a put attempt.
– Gary
Mar 24 at 6:16
Perhaps try printing the reason in your reject callback:
p.then(() => /* fulfilled */ , (reason) -> console.log(reason)). An exception in the executor function would show up here.– jspcal
Mar 24 at 6:10
Perhaps try printing the reason in your reject callback:
p.then(() => /* fulfilled */ , (reason) -> console.log(reason)). An exception in the executor function would show up here.– jspcal
Mar 24 at 6:10
Thanks for responding. It does print a reason which is " DataError: Data provided to an operation does not meet requirements." I assume that is because the key is null. The problem is that, even with this error response, the transaction completes without event error at any level, but it only partially completes when it should roll back. It appears to work properly for an add attempt to an existing key, as I added to my question afterward, but not a null key in a put attempt.
– Gary
Mar 24 at 6:16
Thanks for responding. It does print a reason which is " DataError: Data provided to an operation does not meet requirements." I assume that is because the key is null. The problem is that, even with this error response, the transaction completes without event error at any level, but it only partially completes when it should roll back. It appears to work properly for an add attempt to an existing key, as I added to my question afterward, but not a null key in a put attempt.
– Gary
Mar 24 at 6:16
add a comment |
2 Answers
2
active
oldest
votes
IDBObjectStore.put throws a DataError because the key that was provided is invalid. This exits the function and prevents the request from being created (or executed - so the request callbacks are never invoked).
The transaction completes normally because all the previously executed DB operations succeeded. The promise itself fails because the function threw an exception at the line that attempts to create the invalid request:
req = s[ o.op ]( d );
You could explicitly call abort in the error handler for your promise or catch exceptions within your processing function.
Thank you. In comparison to the add attempt to an exsiting key, which triggers all the expected error events in my code, do you mean that a DataError is treated differently than a ConstraintError, such that in contrast to what you wrote about the DataError not creating the request, a ConstraintError only comes about after the request is created on a valid key and it is later determined that the valid key already exists in the object store? That's a tricky concept for the novice like me to pick up on. Would a try/catch catch the DataError? Of course, I'll test it out and see. Thanks.
– Gary
Mar 24 at 6:53
Many API functions can throw synchronous exceptions, so atry/catcharound everything after the transaction is created would let you handle those and related processing errors.
– jspcal
Mar 24 at 7:04
Thank you. Putting the request in a try/catch and calling abort in the catch solved the problem. I just naively assumed that onerror would catch any error. So, now my pointer data can remain consistent with the actual data. I'll have to start paying closer attention to the Exceptions tables in the MDN documents. Thanks again.
– Gary
Mar 24 at 7:12
add a comment |
My first guess is because you defined a function in a loop. The key issue is this pattern:
for(...)
request.onsuccess = function()
//...
;
There are valid ways to define functions in loops, but the above example is not one. Defining a function within a loop is a messy business in general, so by convention I would recommend just avoiding it entirely. Try this pattern instead:
function outerfunction()
function innerhelperfunction()
for(...)
request.onsuccess = innerhelperfunction;
See, for example, Javascript: Creating Functions in a For Loop
Thanks for responding. I understand some about closures and have run into the problem mentioned in the question you linked to before, concerning whether a variable's value is set at the time a function is declared or at the time it is executed. I'll give it a try but there are no "external" variables, just the event and "this". Also, it appears to work for an add attempt to an existing key, and triggers all the error events in that test scenario, and it worked for the manual abort in the previous use of the try-catch on the JSON.parse attempt. But, I'll give it a try. Thanks.
– Gary
Mar 24 at 6:41
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55320951%2fcatching-errors-and-rollbacks-in-indexeddb%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
IDBObjectStore.put throws a DataError because the key that was provided is invalid. This exits the function and prevents the request from being created (or executed - so the request callbacks are never invoked).
The transaction completes normally because all the previously executed DB operations succeeded. The promise itself fails because the function threw an exception at the line that attempts to create the invalid request:
req = s[ o.op ]( d );
You could explicitly call abort in the error handler for your promise or catch exceptions within your processing function.
Thank you. In comparison to the add attempt to an exsiting key, which triggers all the expected error events in my code, do you mean that a DataError is treated differently than a ConstraintError, such that in contrast to what you wrote about the DataError not creating the request, a ConstraintError only comes about after the request is created on a valid key and it is later determined that the valid key already exists in the object store? That's a tricky concept for the novice like me to pick up on. Would a try/catch catch the DataError? Of course, I'll test it out and see. Thanks.
– Gary
Mar 24 at 6:53
Many API functions can throw synchronous exceptions, so atry/catcharound everything after the transaction is created would let you handle those and related processing errors.
– jspcal
Mar 24 at 7:04
Thank you. Putting the request in a try/catch and calling abort in the catch solved the problem. I just naively assumed that onerror would catch any error. So, now my pointer data can remain consistent with the actual data. I'll have to start paying closer attention to the Exceptions tables in the MDN documents. Thanks again.
– Gary
Mar 24 at 7:12
add a comment |
IDBObjectStore.put throws a DataError because the key that was provided is invalid. This exits the function and prevents the request from being created (or executed - so the request callbacks are never invoked).
The transaction completes normally because all the previously executed DB operations succeeded. The promise itself fails because the function threw an exception at the line that attempts to create the invalid request:
req = s[ o.op ]( d );
You could explicitly call abort in the error handler for your promise or catch exceptions within your processing function.
Thank you. In comparison to the add attempt to an exsiting key, which triggers all the expected error events in my code, do you mean that a DataError is treated differently than a ConstraintError, such that in contrast to what you wrote about the DataError not creating the request, a ConstraintError only comes about after the request is created on a valid key and it is later determined that the valid key already exists in the object store? That's a tricky concept for the novice like me to pick up on. Would a try/catch catch the DataError? Of course, I'll test it out and see. Thanks.
– Gary
Mar 24 at 6:53
Many API functions can throw synchronous exceptions, so atry/catcharound everything after the transaction is created would let you handle those and related processing errors.
– jspcal
Mar 24 at 7:04
Thank you. Putting the request in a try/catch and calling abort in the catch solved the problem. I just naively assumed that onerror would catch any error. So, now my pointer data can remain consistent with the actual data. I'll have to start paying closer attention to the Exceptions tables in the MDN documents. Thanks again.
– Gary
Mar 24 at 7:12
add a comment |
IDBObjectStore.put throws a DataError because the key that was provided is invalid. This exits the function and prevents the request from being created (or executed - so the request callbacks are never invoked).
The transaction completes normally because all the previously executed DB operations succeeded. The promise itself fails because the function threw an exception at the line that attempts to create the invalid request:
req = s[ o.op ]( d );
You could explicitly call abort in the error handler for your promise or catch exceptions within your processing function.
IDBObjectStore.put throws a DataError because the key that was provided is invalid. This exits the function and prevents the request from being created (or executed - so the request callbacks are never invoked).
The transaction completes normally because all the previously executed DB operations succeeded. The promise itself fails because the function threw an exception at the line that attempts to create the invalid request:
req = s[ o.op ]( d );
You could explicitly call abort in the error handler for your promise or catch exceptions within your processing function.
edited Mar 24 at 6:34
answered Mar 24 at 6:29
jspcaljspcal
41.7k45465
41.7k45465
Thank you. In comparison to the add attempt to an exsiting key, which triggers all the expected error events in my code, do you mean that a DataError is treated differently than a ConstraintError, such that in contrast to what you wrote about the DataError not creating the request, a ConstraintError only comes about after the request is created on a valid key and it is later determined that the valid key already exists in the object store? That's a tricky concept for the novice like me to pick up on. Would a try/catch catch the DataError? Of course, I'll test it out and see. Thanks.
– Gary
Mar 24 at 6:53
Many API functions can throw synchronous exceptions, so atry/catcharound everything after the transaction is created would let you handle those and related processing errors.
– jspcal
Mar 24 at 7:04
Thank you. Putting the request in a try/catch and calling abort in the catch solved the problem. I just naively assumed that onerror would catch any error. So, now my pointer data can remain consistent with the actual data. I'll have to start paying closer attention to the Exceptions tables in the MDN documents. Thanks again.
– Gary
Mar 24 at 7:12
add a comment |
Thank you. In comparison to the add attempt to an exsiting key, which triggers all the expected error events in my code, do you mean that a DataError is treated differently than a ConstraintError, such that in contrast to what you wrote about the DataError not creating the request, a ConstraintError only comes about after the request is created on a valid key and it is later determined that the valid key already exists in the object store? That's a tricky concept for the novice like me to pick up on. Would a try/catch catch the DataError? Of course, I'll test it out and see. Thanks.
– Gary
Mar 24 at 6:53
Many API functions can throw synchronous exceptions, so atry/catcharound everything after the transaction is created would let you handle those and related processing errors.
– jspcal
Mar 24 at 7:04
Thank you. Putting the request in a try/catch and calling abort in the catch solved the problem. I just naively assumed that onerror would catch any error. So, now my pointer data can remain consistent with the actual data. I'll have to start paying closer attention to the Exceptions tables in the MDN documents. Thanks again.
– Gary
Mar 24 at 7:12
Thank you. In comparison to the add attempt to an exsiting key, which triggers all the expected error events in my code, do you mean that a DataError is treated differently than a ConstraintError, such that in contrast to what you wrote about the DataError not creating the request, a ConstraintError only comes about after the request is created on a valid key and it is later determined that the valid key already exists in the object store? That's a tricky concept for the novice like me to pick up on. Would a try/catch catch the DataError? Of course, I'll test it out and see. Thanks.
– Gary
Mar 24 at 6:53
Thank you. In comparison to the add attempt to an exsiting key, which triggers all the expected error events in my code, do you mean that a DataError is treated differently than a ConstraintError, such that in contrast to what you wrote about the DataError not creating the request, a ConstraintError only comes about after the request is created on a valid key and it is later determined that the valid key already exists in the object store? That's a tricky concept for the novice like me to pick up on. Would a try/catch catch the DataError? Of course, I'll test it out and see. Thanks.
– Gary
Mar 24 at 6:53
Many API functions can throw synchronous exceptions, so a
try/catch around everything after the transaction is created would let you handle those and related processing errors.– jspcal
Mar 24 at 7:04
Many API functions can throw synchronous exceptions, so a
try/catch around everything after the transaction is created would let you handle those and related processing errors.– jspcal
Mar 24 at 7:04
Thank you. Putting the request in a try/catch and calling abort in the catch solved the problem. I just naively assumed that onerror would catch any error. So, now my pointer data can remain consistent with the actual data. I'll have to start paying closer attention to the Exceptions tables in the MDN documents. Thanks again.
– Gary
Mar 24 at 7:12
Thank you. Putting the request in a try/catch and calling abort in the catch solved the problem. I just naively assumed that onerror would catch any error. So, now my pointer data can remain consistent with the actual data. I'll have to start paying closer attention to the Exceptions tables in the MDN documents. Thanks again.
– Gary
Mar 24 at 7:12
add a comment |
My first guess is because you defined a function in a loop. The key issue is this pattern:
for(...)
request.onsuccess = function()
//...
;
There are valid ways to define functions in loops, but the above example is not one. Defining a function within a loop is a messy business in general, so by convention I would recommend just avoiding it entirely. Try this pattern instead:
function outerfunction()
function innerhelperfunction()
for(...)
request.onsuccess = innerhelperfunction;
See, for example, Javascript: Creating Functions in a For Loop
Thanks for responding. I understand some about closures and have run into the problem mentioned in the question you linked to before, concerning whether a variable's value is set at the time a function is declared or at the time it is executed. I'll give it a try but there are no "external" variables, just the event and "this". Also, it appears to work for an add attempt to an existing key, and triggers all the error events in that test scenario, and it worked for the manual abort in the previous use of the try-catch on the JSON.parse attempt. But, I'll give it a try. Thanks.
– Gary
Mar 24 at 6:41
add a comment |
My first guess is because you defined a function in a loop. The key issue is this pattern:
for(...)
request.onsuccess = function()
//...
;
There are valid ways to define functions in loops, but the above example is not one. Defining a function within a loop is a messy business in general, so by convention I would recommend just avoiding it entirely. Try this pattern instead:
function outerfunction()
function innerhelperfunction()
for(...)
request.onsuccess = innerhelperfunction;
See, for example, Javascript: Creating Functions in a For Loop
Thanks for responding. I understand some about closures and have run into the problem mentioned in the question you linked to before, concerning whether a variable's value is set at the time a function is declared or at the time it is executed. I'll give it a try but there are no "external" variables, just the event and "this". Also, it appears to work for an add attempt to an existing key, and triggers all the error events in that test scenario, and it worked for the manual abort in the previous use of the try-catch on the JSON.parse attempt. But, I'll give it a try. Thanks.
– Gary
Mar 24 at 6:41
add a comment |
My first guess is because you defined a function in a loop. The key issue is this pattern:
for(...)
request.onsuccess = function()
//...
;
There are valid ways to define functions in loops, but the above example is not one. Defining a function within a loop is a messy business in general, so by convention I would recommend just avoiding it entirely. Try this pattern instead:
function outerfunction()
function innerhelperfunction()
for(...)
request.onsuccess = innerhelperfunction;
See, for example, Javascript: Creating Functions in a For Loop
My first guess is because you defined a function in a loop. The key issue is this pattern:
for(...)
request.onsuccess = function()
//...
;
There are valid ways to define functions in loops, but the above example is not one. Defining a function within a loop is a messy business in general, so by convention I would recommend just avoiding it entirely. Try this pattern instead:
function outerfunction()
function innerhelperfunction()
for(...)
request.onsuccess = innerhelperfunction;
See, for example, Javascript: Creating Functions in a For Loop
answered Mar 24 at 6:27
JoshJosh
11.8k63855
11.8k63855
Thanks for responding. I understand some about closures and have run into the problem mentioned in the question you linked to before, concerning whether a variable's value is set at the time a function is declared or at the time it is executed. I'll give it a try but there are no "external" variables, just the event and "this". Also, it appears to work for an add attempt to an existing key, and triggers all the error events in that test scenario, and it worked for the manual abort in the previous use of the try-catch on the JSON.parse attempt. But, I'll give it a try. Thanks.
– Gary
Mar 24 at 6:41
add a comment |
Thanks for responding. I understand some about closures and have run into the problem mentioned in the question you linked to before, concerning whether a variable's value is set at the time a function is declared or at the time it is executed. I'll give it a try but there are no "external" variables, just the event and "this". Also, it appears to work for an add attempt to an existing key, and triggers all the error events in that test scenario, and it worked for the manual abort in the previous use of the try-catch on the JSON.parse attempt. But, I'll give it a try. Thanks.
– Gary
Mar 24 at 6:41
Thanks for responding. I understand some about closures and have run into the problem mentioned in the question you linked to before, concerning whether a variable's value is set at the time a function is declared or at the time it is executed. I'll give it a try but there are no "external" variables, just the event and "this". Also, it appears to work for an add attempt to an existing key, and triggers all the error events in that test scenario, and it worked for the manual abort in the previous use of the try-catch on the JSON.parse attempt. But, I'll give it a try. Thanks.
– Gary
Mar 24 at 6:41
Thanks for responding. I understand some about closures and have run into the problem mentioned in the question you linked to before, concerning whether a variable's value is set at the time a function is declared or at the time it is executed. I'll give it a try but there are no "external" variables, just the event and "this". Also, it appears to work for an add attempt to an existing key, and triggers all the error events in that test scenario, and it worked for the manual abort in the previous use of the try-catch on the JSON.parse attempt. But, I'll give it a try. Thanks.
– Gary
Mar 24 at 6:41
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55320951%2fcatching-errors-and-rollbacks-in-indexeddb%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Perhaps try printing the reason in your reject callback:
p.then(() => /* fulfilled */ , (reason) -> console.log(reason)). An exception in the executor function would show up here.– jspcal
Mar 24 at 6:10
Thanks for responding. It does print a reason which is " DataError: Data provided to an operation does not meet requirements." I assume that is because the key is null. The problem is that, even with this error response, the transaction completes without event error at any level, but it only partially completes when it should roll back. It appears to work properly for an add attempt to an existing key, as I added to my question afterward, but not a null key in a put attempt.
– Gary
Mar 24 at 6:16