@@ -105,7 +105,7 @@ class Transaction {
105
105
// Whether the function is an `async` function. We can't allow those because
106
106
// the isolate could be transferred to another thread during execution.
107
107
// Checking the return value seems like the only thing we can in Dart v2.12.
108
- if (fn is Future Function ()) {
108
+ if (fn is Future Function () && _nullSafetyEnabled ) {
109
109
// This is a special case when the given function always throws. Triggered
110
110
// in our test code. No need to even start a DB transaction in that case.
111
111
if (fn is Never Function ()) {
@@ -124,7 +124,17 @@ class Transaction {
124
124
// thus marking before the call allows us to return directly, before an
125
125
// intermediary variable.
126
126
if (tx._isWrite) tx.markSuccessful ();
127
- return fn ();
127
+ if (_nullSafetyEnabled) {
128
+ return fn ();
129
+ } else {
130
+ final result = fn ();
131
+ if (result is Future ) {
132
+ // Let's make sure users change their code not to do use async.
133
+ throw UnsupportedError (
134
+ 'Executing an "async" function in a transaction is not allowed.' );
135
+ }
136
+ return result;
137
+ }
128
138
} catch (ex) {
129
139
if (tx._isWrite) tx.markFailed ();
130
140
rethrow ;
@@ -133,3 +143,8 @@ class Transaction {
133
143
}
134
144
}
135
145
}
146
+
147
+ /// True if the package enables null-safety (i.e. depends on SDK 2.12+).
148
+ /// Otherwise, it's we can distinguish at runtime whether a function is async.
149
+ final _nullSafetyEnabled = _nullReturningFn is ! Future Function ();
150
+ final _nullReturningFn = () => null ;
0 commit comments