Question

When you reach the size limit for your web sql store, Mobile Safari (and the Android browser) will prompt you to increase the storage size. Once that happens, neither the transaction, onSuccess callback or onError callback is executed. I cannot seem to catch any exceptions here either, so how am I supposed to handle prompts for increased storage?

All the operations are async, so I can only think of setting a timeout and checking if the transaction completed after some time has gone. Which of course is a nasty, bug-ridden hack. And in addition to that, I have to re-do the transaction to actually check if the space was increased or not.

Fiddle for verifying on mobile browser

    // open the jsfiddle in safari

    // refuse when prompted to increase space to show the bug
    db.transaction(function (tx) {
        tx.executeSql("INSERT INTO key_value(key, value) VALUES(?,?);", ["mykey", buildBigString(3*Math.pow(10,6))], function (tx, result) {
        // will never be called
        done();
        }, function (tx, error) {
        // will never be called
            done();
        });
    });
Était-ce utile?

La solution

The problem with the above code was basically that I was missing an error callback for the transaction wrapping the sql insertion. For more info on generally how to actually handle user prompts, see this elaborated blog post on the matter.

From the specification on the Asynchronous Database API

void transaction(in SQLTransactionCallback callback, 
                 in optional SQLTransactionErrorCallback errorCallback,
                 in optional SQLVoidCallback successCallback);

No example code showed this, and so I kept on assuming the transaction method was used without callbacks.

So instead of writing

db.transaction(function (tx) {
 // if this prompts the user to increase the size it will not execute the sql or run any of the callbacks
 tx.executeSql('INSERT INTO foo (id, text) VALUES (1, createReallyBigString('4MB')', onComplete, onError );
 });

Do this

// Note the reverse order of the callbacks!
 db.transaction(function (tx) {
 // this will prompt the user to increase the size and the sql will not be executed
 tx.executeSql('INSERT INTO foo (id, text) VALUES (1, createReallyBigString('4MB')');
 }, onError, onComplete );
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top