Skip to content

Commit b416473

Browse files
[flutter_tools] catch StdinException when setting terminal to SingleCharMode (#136283)
Fixes #129198
1 parent 54cf286 commit b416473

3 files changed

Lines changed: 60 additions & 9 deletions

File tree

packages/flutter_tools/lib/src/base/terminal.dart

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,19 @@ class AnsiTerminal implements Terminal {
314314
return;
315315
}
316316
final io.Stdin stdin = _stdio.stdin as io.Stdin;
317-
// The order of setting lineMode and echoMode is important on Windows.
318-
if (value) {
319-
stdin.echoMode = false;
320-
stdin.lineMode = false;
321-
} else {
322-
stdin.lineMode = true;
323-
stdin.echoMode = true;
317+
318+
try {
319+
// The order of setting lineMode and echoMode is important on Windows.
320+
if (value) {
321+
stdin.echoMode = false;
322+
stdin.lineMode = false;
323+
} else {
324+
stdin.lineMode = true;
325+
stdin.echoMode = true;
326+
}
327+
} on io.StdinException {
328+
// If the pipe to STDIN has been closed it's probably because the
329+
// terminal has been closed, and there is nothing actionable to do here.
324330
}
325331
}
326332

packages/flutter_tools/test/general.shard/base/terminal_test.dart

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:flutter_tools/src/base/terminal.dart';
99
import 'package:test/fake.dart';
1010

1111
import '../../src/common.dart';
12+
import '../../src/fakes.dart';
1213

1314
void main() {
1415
group('output preferences', () {
@@ -253,6 +254,16 @@ void main() {
253254
expect(AnsiTerminal(stdio: stdio, platform: const LocalPlatform(), now: DateTime(2018, 1, 10, 23)).preferredStyle, 2);
254255
expect(AnsiTerminal(stdio: stdio, platform: const LocalPlatform(), now: DateTime(2018, 1, 11, 23)).preferredStyle, 3);
255256
});
257+
258+
testWithoutContext('set singleCharMode resilient to StdinException', () async {
259+
final FakeStdio stdio = FakeStdio();
260+
final AnsiTerminal terminal = AnsiTerminal(stdio: stdio, platform: const LocalPlatform());
261+
stdio.stdinHasTerminal = true;
262+
stdio._stdin = FakeStdin()..echoModeCallback = (bool _) => throw const StdinException(
263+
'Error setting terminal echo mode, OS Error: The handle is invalid.',
264+
);
265+
terminal.singleCharMode = true;
266+
});
256267
}
257268

258269
late Stream<String> mockStdInStream;
@@ -269,14 +280,36 @@ class TestTerminal extends AnsiTerminal {
269280
return mockStdInStream;
270281
}
271282

283+
bool _singleCharMode = false;
284+
272285
@override
273-
bool singleCharMode = false;
286+
bool get singleCharMode => _singleCharMode;
287+
288+
void Function(bool newMode)? _singleCharModeCallback;
289+
290+
@override
291+
set singleCharMode(bool newMode) {
292+
_singleCharMode = newMode;
293+
if (_singleCharModeCallback != null) {
294+
_singleCharModeCallback!(newMode);
295+
}
296+
}
274297

275298
@override
276299
int get preferredStyle => 0;
277300
}
278301

279302
class FakeStdio extends Fake implements Stdio {
303+
Stream<List<int>>? _stdin;
304+
305+
@override
306+
Stream<List<int>> get stdin {
307+
if (_stdin != null) {
308+
return _stdin!;
309+
}
310+
throw UnimplementedError('stdin');
311+
}
312+
280313
@override
281314
bool stdinHasTerminal = false;
282315
}

packages/flutter_tools/test/src/fakes.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,20 @@ class FakeStdio extends Stdio {
253253
class FakeStdin extends Fake implements Stdin {
254254
final StreamController<List<int>> controller = StreamController<List<int>>();
255255

256+
void Function(bool mode)? echoModeCallback;
257+
258+
bool _echoMode = true;
259+
260+
@override
261+
bool get echoMode => _echoMode;
262+
256263
@override
257-
bool echoMode = true;
264+
set echoMode(bool mode) {
265+
_echoMode = mode;
266+
if (echoModeCallback != null) {
267+
echoModeCallback!(mode);
268+
}
269+
}
258270

259271
@override
260272
bool lineMode = true;

0 commit comments

Comments
 (0)