Ionic SQLite plugin always throws an exception when deleting - ionic-framework

I have an SQLite database, testing on my Android device, with a simple table, where whenever I execute a delete, it wlays throws an exception, even though the delete succeeds. I can tell it has succeed as the data is gone from the database.
My SQL looks like the following…
let db = await this.sqlite.create({name: 'mydb.sqlite', location: 'default'});
let delSql = `DELETE FROM ${this.TABLE_NAME} WHERE GroupName = '${groupName}' AND Id IN ('CAR01','CAR02');
await db.executeSql(delSql);
Catching the exception, it will always throw..
I have tried to follow the source for the plugin it wraps here, but, as we can see at line 163..
try {
rowsAffected = myStatement.executeUpdateDelete();
// Indicate valid results:
needRawQuery = false;
rowsAffected seems to be set if no exception is thrown, yet in my case (as in the screenshot) this comes back as 9, yet I still get an exception.
Has anyone else encountered this, or have any ideas why I always get an exception?
Thanks in advance for any help.

Related

How to request data from Firestore defensively with Flutter

Since Firestore is a NoSQL database and has no strict type rules and defined document structures, I think about handling corrupt data in my Flutter app.
In case you wonder why I want to request defensively, even when it is no third-party API -> I can think of three reasons why my app crashes because of corrupt data:
I add wrong data via the Firebase console like using type string for a field that should have been type number (happened repeatedly).
A bug in my app adds corrupt data to Firestore.
A user has an old version of my app installed which can not handle the new Firestore data structure.
My requirements: The app should not crash when corrupt data from Firestore is requested, but the corrupt data should be reported so that the data can be fixed in Firestore a.s.a.p.
What do you think about the following approach?
Assume we have a model Movie.
Movie {
final String title;
final int releaseYear;
Movie({required this.title, required this.releaseYear});
Movie.from(Map<String, dynamic> data)
: title = data['title'],
releaseYear = data['release_year'];
}
The named constructor from parses the document data from DocumentSnapshot.data() and returns our model. This works fine as long as the data has a field title of type String and a field release_year of type int (number in Firestore).
Let's assume the field release_year is missing in the actual data. This will let the request crash. Thus, the current user can't do anything with the respective movie and I as developer won't notice, because it happened silently on the device of the user.
To fix the first issue, we can use defensive parsing with fallback data like this: data['release_year'] ?? -1. No crash happens, but I as developer still don't notice and can't fix the data.
To fix also this issue we could use Firebase Crashlytics. The only problem is that if we use defensive parsing to prevent crashing no log will be sent to Firebase. That's why I came up with this solution:
final snapshot = await FirebaseFirestore.instance.collection('movies').doc('123').get();
try {
return Movie.from(snapshot.data()!);
} catch (e) {
await FirebaseCrashlytics.instance
.recordError(e, e.stackTrace(), reason: 'data of movie ${snapshot.id} is corrupt');
return Movie.fromCorrupt(snapshot.data()!);
}
First, the app tries to parse the document data without any fallback mechanism. If the data is corrupt an exception is thrown and catched. In the catch block, the error is send to Firebase and then the defensive parsing constructor fromCorrupt is called to let the user continue in the app with the remaining data. In fromCorrupt each field is checked on null and type, before it is used to create the model Movie. If a value is null or of a wrong type, a fallback value is used.
What do you think of my approach? Am I overengineering? 😅

How to pass exceptions in Dart?

I am Currently working with puppeteer Dart package, as you see in this code below.
try {
await page.waitForXPath('//*[#id="confirm-yes"]');
var confirm = await page.$x('//*[#id="confirm-yes"]');
await confirm[0].click();
}catch (e) {
print(e)
}
the code above works fine, i use it on my other tasks, however in this particular step the selector is a popup and it sometimes come up and sometimes doesnt, and so i want it to be like if the popup comes up this above code will identify the selector element and click on it, but if it isnt available than just skip this and move on, however it just gives out an exception and breaks the code. i am very new to dart in python i would have just written pass in exception block.
please help.

Why does Firebase not support onDisconnect when app crashes?

I am used that I have a little bug resulting in an app crash. Most likely the bug occurs when querying data from Firebase (yeah yeah, my fault). This is the first function that will be executed when the app launches:
let currentUser = FIRAuth.auth()?.currentUser?.uid
let con = self.gameRef!.childByAutoId()
self.usersKey = con.key
let values = ["username": "test", "score": 0, "userID": currentUser!] as [String : Any]
con.updateChildValues(values)
con.onDisconnectRemoveValue()
Then after this is set, I query for example an array from Firebase but I did set some values wrong what results in an app crash. The onDisconnected function is never executed. I waited for a whole day and my information is still showed in the realtime database. If this code is executed server side, how can it be that the server still thinks I am connected? Closing the app & turning on airplane mode will disconnect me correctly.
This happens because your app isn't shutting down properly. In order for that function to fire it has to be when the app shuts down and cleans up all of its connections. There is no way for it to do this when it crashes because it won't execute any more code than it already did.
You could wrap an exception handler around that part of the code and then execute what you need on that exception.

General pattern for failing over from one database to another using Entity Framework?

We have an enterprise DB that is replicated through many sites throughout the world. We would like our app to attempt to connect to one of the local sites, and if that site is down we want it to fall back to the enterprise DB. We'd like this behavior on each of our DB operations.
We are using Entity Framework, C#, and SQL Server.
At first I hoped I could just specify a "Failover Partner" in the connection string, but that only works in a mirrored DB environment, which this is not. I also looked into writing a custom IDbExecutionStrategy. But these strategies only allow you to specify the pattern for retrying a failed DB operation. It does not allow you to change the operation in any way like directing it to a new connection.
So, do you know of any good pattern for dealing with this type of operation, other than duplicating retry logic around each of our many DB operations?
Update on 2014-05-14:
I'll elaborate in response to some of the suggestions already made.
I have many places where the code looks like this:
try
{
using(var db = new MyDBContext(ConnectionString))
{
// Database operations here.
// var myList = db.MyTable.Select(...), etc.
}
}
catch(Exception ex)
{
// Log exception here, perhaps rethrow.
}
It was suggested that I have a routine that first checks each of the connections strings and returns the first one that successfully connects. This is reasonable as far as it goes. But some of the errors I'm seeing are timeouts on the operations, where the connection works but the DB has issues that keep it from completing the operation.
What I'm looking for is a pattern I can use to encapsulate the unit of work and say, "Try this on the first database. If it fails for any reason, rollback and try it on the second DB. If that fails, try it on the third, etc. until the operation succeeds or you have no more DBs." I'm pretty sure I can roll my own (and I'll post the result if I do), but I was hoping there might be a known way to approach this.
How about using some Dependency Injection system like autofac and registering there a factory for new context objects - it will execute logic that will try to connect first to local and in case of failure it will connect to enterprise db. Then it will return ready DbContext object. This factory will be provided to all objects that require it with Dependency Injection system - they will use it to create contexts and dispose of them when they are not needed any more.
" We would like our app to attempt to connect to one of the local sites, and if that site is down we want it to fall back to the enterprise DB. We'd like this behavior on each of our DB operations."
If your app is strictly read-only on the DB and data consistency is not absolutely vital to your app/users, then it's just a matter of trying to CONNECT until an operational site has been found. As M.Ali suggested in his remark.
Otherwise, I suggest you stop thinking along these lines immediately because you're just running 90 mph down a dead end street. As Viktor Zychla suggested in his remark.
Here is what I ended up implementing, in broad brush-strokes:
Define delegates called UnitOfWorkMethod that will execute a single Unit of Work on the Database, in a single transaction. It takes a connection string and one also returns a value:
delegate T UnitOfWorkMethod<out T>(string connectionString);
delegate void UnitOfWorkMethod(string connectionString);
Define a method called ExecuteUOW, that will take a unit of work and method try to execute it using the preferred connection string. If it fails, it tries to execute it with the next connection string:
protected T ExecuteUOW<T>(UnitOfWorkMethod<T> method)
{
// GET THE LIST OF CONNECTION STRINGS
IEnumerable<string> connectionStringList = ConnectionStringProvider.GetConnectionStringList();
// WHILE THERE ARE STILL DATABASES TO TRY, AND WE HAVEN'T DEFINITIVELY SUCCEDED OR FAILED
var uowState = UOWStateEnum.InProcess;
IEnumerator<string> stringIterator = connectionStringList.GetEnumerator();
T returnVal = default(T);
Exception lastException = null;
string connectionString = null;
while ((uowState == UOWStateEnum.InProcess) && stringIterator.MoveNext())
{
try
{
// TRY TO EXECUTE THE UNIT OF WORK AGAINST THE DB.
connectionString = stringIterator.Current;
returnVal = method(connectionString);
uowState = UOWStateEnum.Success;
}
catch (Exception ex)
{
lastException = ex;
// IF IT FAILED BECAUSE OF A TRANSIENT EXCEPTION,
if (TransientChecker.IsTransient(ex))
{
// LOG THE EXCEPTION AND TRY AGAINST ANOTHER DB.
Log.TransientDBException(ex, connectionString);
}
// ELSE
else
{
// CONSIDER THE UOW FAILED.
uowState = UOWStateEnum.Failed;
}
}
}
// LOG THE FAILURE IF WE HAVE NOT SUCCEEDED.
if (uowState != UOWStateEnum.Success)
{
Log.ExceptionDuringDataAccess(lastException);
returnVal = default(T);
}
return returnVal;
}
Finally, for each operation we define our unit of work delegate method. Here an example
UnitOfWorkMethod uowMethod =
(providerConnectionString =>
{
using (var db = new MyContext(providerConnectionString ))
{
// Do my DB commands here. They will roll back if exception thrown.
}
});
ExecuteUOW(uowMethod);
When ExecuteUOW is called, it tries the delegate on each database until it either succeeds or fails on all of them.
I'm going to accept this answer since it fully addresses all of concerns raised in the original question. However, if anyone provides and answer that is more elegant, understandable, or corrects flaws in this one I'll happily accept it instead.
Thanks to all who have responded.

Quickly Testing Database Connectivity within the Entity Framework

[I am new to ADO.NET and the Entity Framework, so forgive me if this questions seems odd.]
In my WPF application a user can switch between different databases at run time. When they do this I want to be able to do a quick check that the database is still available. What I have easily available is the ObjectContext. The test I am preforming is getting the count on the total records of a very small table and if it returns results then it passed, if I get an exception then it fails. I don't like this test, it seemed the easiest to do with the ObjectContext.
I have tried setting the connection timeout it in the connection string and on the ObjectConntext and either seem to change anything for the first scenario, while the second one is already fast so it isn't noticeable if it changes anything.
Scenario One
If the connect was down when before first access it takes about 30 seconds before it gives me the exception that the underlying provider failed.
Scenario Two
If the database was up when I started the application and I access it, and then the connect drops while using the test is quick and returns almost instantly.
I want the first scenario described to be as quick as the second one.
Please let me know how best to resolve this, and if there is a better way to test the connectivity to a DB quickly please advise.
There really is no easy or quick way to resolve this. The ConnectionTimeout value is getting ignored with the Entity Framework. The solution I used is creating a method that checks if a context is valid by passing in the location you which to validate and then it getting the count from a known very small table. If this throws an exception the context is not valid otherwise it is. Here is some sample code showing this.
public bool IsContextValid(SomeDbLocation location)
{
bool isValid = false;
try
{
context = GetContext(location);
context.SomeSmallTable.Count();
isValid = true;
}
catch
{
isValid = false;
}
return isValid;
}
You may need to use context.Database.Connection.Open()