Fix analysis throwing string (#91435)
This commit is contained in:
parent
5883a6628d
commit
b0810bc939
@ -125,7 +125,12 @@ class AnalyzeOnce extends AnalyzeBase {
|
||||
// Completing the future in the callback can't fail.
|
||||
unawaited(server.onExit.then<void>((int exitCode) {
|
||||
if (!analysisCompleter.isCompleted) {
|
||||
analysisCompleter.completeError('analysis server exited: $exitCode');
|
||||
analysisCompleter.completeError(
|
||||
// Include the last 20 lines of server output in exception message
|
||||
Exception(
|
||||
'analysis server exited with code $exitCode and output:\n${server.getLogs(20)}',
|
||||
),
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -79,7 +79,7 @@ class AnalysisServer {
|
||||
final Stream<String> errorStream = _process!.stderr
|
||||
.transform<String>(utf8.decoder)
|
||||
.transform<String>(const LineSplitter());
|
||||
errorStream.listen(_logger.printError);
|
||||
errorStream.listen(_handleError);
|
||||
|
||||
final Stream<String> inStream = _process!.stdout
|
||||
.transform<String>(utf8.decoder)
|
||||
@ -94,6 +94,28 @@ class AnalysisServer {
|
||||
<String, dynamic>{'included': directories, 'excluded': <String>[]});
|
||||
}
|
||||
|
||||
final List<String> _logs = <String>[];
|
||||
|
||||
/// Aggregated STDOUT and STDERR logs from the server.
|
||||
///
|
||||
/// This can be surfaced to the user if the server crashes. If [tail] is null,
|
||||
/// returns all logs, else only the last [tail] lines.
|
||||
String getLogs([int? tail]) {
|
||||
if (tail == null) {
|
||||
return _logs.join('\n');
|
||||
}
|
||||
// Since List doesn't implement a .tail() method, we reverse it then use
|
||||
// .take()
|
||||
final Iterable<String> reversedLogs = _logs.reversed;
|
||||
final List<String> firstTailLogs = reversedLogs.take(tail).toList();
|
||||
return firstTailLogs.reversed.join('\n');
|
||||
}
|
||||
|
||||
void _handleError(String message) {
|
||||
_logs.add('[stderr] $message');
|
||||
_logger.printError(message);
|
||||
}
|
||||
|
||||
bool get didServerErrorOccur => _didServerErrorOccur;
|
||||
|
||||
Stream<bool> get onAnalyzing => _analyzingController.stream;
|
||||
@ -113,6 +135,7 @@ class AnalysisServer {
|
||||
}
|
||||
|
||||
void _handleServerResponse(String line) {
|
||||
_logs.add('[stdout] $line');
|
||||
_logger.printTrace('<== $line');
|
||||
|
||||
final dynamic response = json.decode(line);
|
||||
|
@ -312,7 +312,6 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
return <String>[];
|
||||
}
|
||||
|
||||
|
||||
final List<String> projectPaths = globals.fs.directory(rootPath)
|
||||
.listSync(followLinks: false)
|
||||
.expand((FileSystemEntity entity) {
|
||||
|
@ -4,15 +4,25 @@
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:file/file.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/base/terminal.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/commands/analyze.dart';
|
||||
import 'package:flutter_tools/src/commands/analyze_base.dart';
|
||||
import 'package:flutter_tools/src/dart/analysis.dart';
|
||||
|
||||
import '../../src/common.dart';
|
||||
import '../../src/context.dart';
|
||||
import '../../src/fake_process_manager.dart';
|
||||
import '../../src/test_flutter_command_runner.dart';
|
||||
|
||||
const String _kFlutterRoot = '/data/flutter';
|
||||
const int SIGABRT = -6;
|
||||
|
||||
void main() {
|
||||
testWithoutContext('analyze generate correct errors message', () async {
|
||||
@ -35,6 +45,80 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
group('analyze command', () {
|
||||
FileSystem fileSystem;
|
||||
Platform platform;
|
||||
BufferLogger logger;
|
||||
FakeProcessManager processManager;
|
||||
Terminal terminal;
|
||||
AnalyzeCommand command;
|
||||
CommandRunner<void> runner;
|
||||
|
||||
setUpAll(() {
|
||||
Cache.disableLocking();
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
fileSystem = MemoryFileSystem.test();
|
||||
platform = FakePlatform();
|
||||
logger = BufferLogger.test();
|
||||
processManager = FakeProcessManager.empty();
|
||||
terminal = Terminal.test();
|
||||
command = AnalyzeCommand(
|
||||
artifacts: Artifacts.test(),
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
platform: platform,
|
||||
processManager: processManager,
|
||||
terminal: terminal,
|
||||
);
|
||||
runner = createTestCommandRunner(command);
|
||||
|
||||
// Setup repo roots
|
||||
const String homePath = '/home/user/flutter';
|
||||
Cache.flutterRoot = homePath;
|
||||
for (final String dir in <String>['dev', 'examples', 'packages']) {
|
||||
fileSystem.directory(homePath).childDirectory(dir).createSync(recursive: true);
|
||||
}
|
||||
});
|
||||
|
||||
testUsingContext('SIGABRT throws Exception', () async {
|
||||
const String stderr = 'Something bad happened!';
|
||||
processManager.addCommands(
|
||||
<FakeCommand>[
|
||||
const FakeCommand(
|
||||
// artifact paths are from Artifacts.test() and stable
|
||||
command: <String>[
|
||||
'HostArtifact.engineDartSdkPath/bin/dart',
|
||||
'--disable-dart-dev',
|
||||
'HostArtifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
|
||||
'--disable-server-feature-completion',
|
||||
'--disable-server-feature-search',
|
||||
'--sdk',
|
||||
'HostArtifact.engineDartSdkPath',
|
||||
],
|
||||
exitCode: SIGABRT,
|
||||
stderr: stderr,
|
||||
),
|
||||
],
|
||||
);
|
||||
await expectLater(
|
||||
runner.run(<String>['analyze']),
|
||||
throwsA(
|
||||
isA<Exception>().having(
|
||||
(Exception e) => e.toString(),
|
||||
'description',
|
||||
contains('analysis server exited with code $SIGABRT and output:\n[stderr] $stderr'),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
});
|
||||
|
||||
testWithoutContext('analyze inRepo', () {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
fileSystem.directory(_kFlutterRoot).createSync(recursive: true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user