Skip to content

Commit 7c5dce3

Browse files
Merge pull request #1252 from QueryaHub/chore/1241-async-lints
chore(lint): enable unawaited_futures, cancel_subscriptions, close_sinks and avoid_void_async (#1241)
2 parents fd709ba + 5fc940f commit 7c5dce3

18 files changed

Lines changed: 74 additions & 33 deletions

‎analysis_options.yaml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,8 @@ linter:
2222
rules:
2323
- prefer_const_constructors
2424
- prefer_const_declarations
25+
- unawaited_futures
26+
- cancel_subscriptions
27+
- close_sinks
28+
- avoid_void_async
2529

‎lib/core/database/connection_pool_lock.dart‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class PoolEntryLock<T> {
3131
// Ensure the pending entry is removed once the creation finishes, and
3232
// swallow errors on the cleanup chain so they don't become unhandled.
3333
final guarded = future.whenComplete(() => _pending.remove(key));
34-
guarded.then((_) {}, onError: (_) {});
34+
unawaited(guarded.then((_) {}, onError: (_) {}));
3535
result = future;
3636
}
3737
} finally {

‎lib/core/database/mongodb_connection.dart‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ class MongoConnection {
399399
_openedDbs[databaseName] = db;
400400
return db;
401401
} finally {
402-
_openingDbs.remove(databaseName);
402+
unawaited(_openingDbs.remove(databaseName));
403403
}
404404
});
405405
}

‎lib/core/mcp/mcp_socket_host.dart‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,25 @@ class McpSocketHost {
116116
unawaited(onSession(StreamChannel.withCloseGuarantee(
117117
incoming.stream, outgoing.sink)));
118118
},
119-
onDone: () => _closed(socket, incoming, authed),
120-
onError: (_) => _closed(socket, incoming, authed),
119+
onDone: () => _closed(socket, incoming, outgoing, authed),
120+
onError: (_) => _closed(socket, incoming, outgoing, authed),
121121
cancelOnError: true,
122122
);
123123
}
124124

125-
void _closed(Socket socket, StreamController<String> incoming, bool authed) {
125+
void _closed(
126+
Socket socket,
127+
StreamController<String> incoming,
128+
StreamController<String> outgoing,
129+
bool authed,
130+
) {
126131
if (_sockets.remove(socket) && authed) {
127132
_sessions--;
128133
_changes.add(null);
129134
}
130135
unawaited(incoming.close());
136+
// The channel guarantees no write after the incoming side closed.
137+
unawaited(outgoing.close());
131138
socket.destroy();
132139
}
133140

‎lib/core/security/ssh_tunnel_manager.dart‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ class _PooledTunnelSession {
8080
await serverSocket.close();
8181
} catch (_) {}
8282
try {
83-
client.close();
83+
unawaited(client.close());
8484
} catch (_) {}
8585
try {
86-
jumpClient?.close();
86+
unawaited(jumpClient?.close());
8787
} catch (_) {}
8888
}
8989
}
@@ -274,8 +274,8 @@ class SshTunnelManager {
274274
try {
275275
await client.authenticated;
276276
} catch (e) {
277-
client.close();
278-
jumpClient?.close();
277+
unawaited(client.close());
278+
unawaited(jumpClient?.close());
279279
if (observedFingerprint != null &&
280280
config.knownHostFingerprint != null &&
281281
config.knownHostFingerprint!.isNotEmpty) {
@@ -303,8 +303,8 @@ class SshTunnelManager {
303303
(clientSocket) async {
304304
try {
305305
final forward = await client.forwardLocal(remoteHost, remotePort);
306-
forward.stream.cast<List<int>>().pipe(clientSocket).catchError((_) {});
307-
clientSocket.cast<List<int>>().pipe(forward.sink).catchError((_) {});
306+
unawaited(forward.stream.cast<List<int>>().pipe(clientSocket).catchError((_) {}));
307+
unawaited(clientSocket.cast<List<int>>().pipe(forward.sink).catchError((_) {}));
308308
} catch (e) {
309309
clientSocket.destroy();
310310
}
@@ -461,7 +461,7 @@ class SshTunnelManager {
461461
testRemoteHost.trim(),
462462
testRemotePort,
463463
);
464-
forward.close();
464+
unawaited(forward.close());
465465
} catch (e) {
466466
return SshTestResult(
467467
ok: false,
@@ -483,8 +483,8 @@ class SshTunnelManager {
483483
error: 'SSH Connection failed: $e',
484484
);
485485
} finally {
486-
client?.close();
487-
jumpClient?.close();
486+
unawaited(client?.close());
487+
unawaited(jumpClient?.close());
488488
}
489489
}
490490
}

‎lib/main.dart‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import 'core/theme/theme_controller.dart';
1717
import 'features/updater/update_controller.dart';
1818

1919
void main([List<String> args = const []]) async {
20-
runZonedGuarded(() async {
20+
unawaited(runZonedGuarded(() async {
2121
WidgetsFlutterBinding.ensureInitialized();
2222
FileLaunchService.instance.processLaunchArguments(args);
2323

@@ -46,5 +46,5 @@ void main([List<String> args = const []]) async {
4646
});
4747
}, (error, stack) {
4848
debugPrint('Unhandled async error: $error\n$stack');
49-
});
49+
}));
5050
}

‎test/core/extensions/harness/extension_harness_test.dart‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@ class _FakePlugin implements HarnessPluginProcess {
3434
final calls = <String>[];
3535
final _stdout = StreamController<List<int>>();
3636
final _stderr = StreamController<List<int>>();
37+
// The fake owns this stream for the whole test.
38+
// ignore: close_sinks
3739
final _stdinController = StreamController<List<int>>();
3840
final _exit = Completer<int>();
41+
// The fake owns this stream for the whole test.
42+
// ignore: close_sinks
3943
late final IOSink _stdin = IOSink(_stdinController);
4044

4145
void _reply(Map<String, Object?> body) {

‎test/core/extensions/rpc/json_rpc_stdio_client_test.dart‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ void main() {
160160
var peakAhead = 0;
161161
var handled = 0;
162162
for (final r in replies) {
163-
r.then((_) => handled++);
163+
unawaited(r.then((_) => handled++));
164164
}
165165
final watcher = Timer.periodic(const Duration(milliseconds: 1), (_) {
166166
peakAhead = math.max(peakAhead, produced - handled);

‎test/core/extensions/rpc/plugin_rpc_bridge_test.dart‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class _FakeProcess implements Process {
3434
int get pid => 99;
3535

3636
@override
37+
// The fake owns this stream for the whole test.
38+
// ignore: close_sinks
3739
late final IOSink stdin;
3840

3941
@override

‎test/core/extensions/sandbox/sandbox_credentials_injector_test.dart‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class _FakeProcess implements Process {
3232
int get pid => 4242;
3333

3434
@override
35+
// The fake owns this stream for the whole test.
36+
// ignore: close_sinks
3537
late final IOSink stdin;
3638

3739
@override
@@ -131,6 +133,8 @@ void main() {
131133
group('JsonRpcStdioClient', () {
132134
test('sends request and completes with result', () async {
133135
final stdout = StreamController<List<int>>();
136+
// The fake owns this stream for the whole test.
137+
// ignore: close_sinks
134138
final stdin = StreamController<List<int>>();
135139
final client = JsonRpcStdioClient(
136140
stdout: stdout.stream,
@@ -158,6 +162,8 @@ void main() {
158162

159163
test('maps JSON-RPC errors', () async {
160164
final stdout = StreamController<List<int>>();
165+
// The fake owns this stream for the whole test.
166+
// ignore: close_sinks
161167
final stdin = StreamController<List<int>>();
162168
final client = JsonRpcStdioClient(
163169
stdout: stdout.stream,

0 commit comments

Comments
 (0)