I got the following Error when using transactions in Isolates.
NoSuchMethodError: The method 'send' was called on null.
Receiver: null
Tried calling: send()
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1 _MoorServer._transactionControl (package:moor/src/runtime/isolate/server.dart:129:29)
#2 _MoorServer._handleRequest (package:moor/src/runtime/isolate/server.dart:77:14)
#3 IsolateCommunication.setRequestHandler.<anonymous closure> (package:moor/src/runtime/isolate/communication.dart:138:31)
#4 _RootZone.runUnaryGuarded (dart:async/zone.dart:1316:10)
#5 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:338:11)
#6 _DelayedData.perform (dart:async/stream_impl.dart:593:14)
#7 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:709:11)
#8 _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:669:7)
#9 _microtaskLoop (dart:async/schedule_microtask.dart:43:21)
#10 _startMicrotaskLoop (dart:async/sched<…>
As far as I understood it in #242 , this bug should actually be fixed with version 2.3.0. Unfortunately it still occurs in the newest version.
What I have noticed so far is that the transactionId is 0 first. But the second transaction is again null, so the error is thrown.
Edit
As a quick fix, I have again added
await transactionExecutor.ensureOpen();
to the transaction function in query_engine.dart. This at least fixes the error for me.
Thank you for the report.
But the second transaction is again null, so the error is thrown.
I couldn't reproduce this. In my tests, I use this setup to run multiple transactions with multiple statements:
await transaction(() async {
await into(todosTable).insert(initialCompanion);
await into(todosTable).insert(initialCompanion);
});
await transaction(() async {
await into(todosTable).insert(initialCompanion);
await into(todosTable).insert(initialCompanion);
});
That seems to work fine though. Can you provide a short repro for me to try? Thanks!
Hi @simolus3
I've been testing around for quite a while now and found the actual error. I don't know if the error is on my side and if it is the desired behavior of moor .
I have a transaction that looks like this:
Future<void> insertUsers(List<User> allUser) {
return transaction(() async {
for (User user in allUser) {
await (into(users).insert(UsersCompanion(
name: Value(user.name),
)));
}
});
}
The transaction works as long as allUsers isn't an empty List. In case allUsers is empty the transaction fails with The method 'send' was called on null. error.
This is probably because transaction.complete() is called before the transaction is known in the executor. Therefore the error does not occur if you call await transactionExecutor.ensureOpen(); before.
If this is the desired behavior of a transaction, I would ask you to write a warning in the documentation that at least one query should always be executed within a transaction.
Oh that's a very good catch, thank you! Moor should definitely not crash when completing an unused transaction. I'll fix this for the next version.
This will be fixed in the next version. Thanks again for the report!
Most helpful comment
Oh that's a very good catch, thank you! Moor should definitely not crash when completing an unused transaction. I'll fix this for the next version.