diff --git a/packages/flutter_tools/analysis_options.yaml b/packages/flutter_tools/analysis_options.yaml index 525929f5b0b..139938dcf4d 100644 --- a/packages/flutter_tools/analysis_options.yaml +++ b/packages/flutter_tools/analysis_options.yaml @@ -7,3 +7,4 @@ linter: rules: unawaited_futures: true curly_braces_in_flow_control_structures: true + avoid_catches_without_on_clauses: true diff --git a/packages/flutter_tools/lib/runner.dart b/packages/flutter_tools/lib/runner.dart index 4dd5631da90..9d75c1e5095 100644 --- a/packages/flutter_tools/lib/runner.dart +++ b/packages/flutter_tools/lib/runner.dart @@ -62,7 +62,8 @@ Future run( try { await runner.run(args); return await _exit(0); - } catch (error, stackTrace) { + // This catches all exceptions to send to crash logging, etc. + } catch (error, stackTrace) { // ignore: avoid_catches_without_on_clauses firstError = error; firstStackTrace = stackTrace; return await _handleToolError( @@ -135,7 +136,8 @@ Future _handleToolError( await _informUserOfCrash(args, error, stackTrace, errorString); return _exit(1); - } catch (error) { + // This catch catches all exceptions to ensure the message below is printed. + } catch (error) { // ignore: avoid_catches_without_on_clauses globals.stdio.stderrWrite( 'Unable to generate crash report due to secondary error: $error\n' 'please let us know at https://github.com/flutter/flutter/issues.\n', @@ -243,7 +245,7 @@ Future _doctorText() async { ); return logger.statusText; - } catch (error, trace) { + } on Exception catch (error, trace) { return 'encountered exception: $error\n\n${trace.toString().trim()}\n'; } } @@ -271,7 +273,9 @@ Future _exit(int code) async { globals.printTrace('exiting with code $code'); exit(code); completer.complete(); - } catch (error, stackTrace) { + // This catches all exceptions becauce the error is propagated on the + // completer. + } catch (error, stackTrace) { // ignore: avoid_catches_without_on_clauses completer.completeError(error, stackTrace); } }); diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index 53a0065afd0..975fd271707 100644 --- a/packages/flutter_tools/lib/src/android/android_device.dart +++ b/packages/flutter_tools/lib/src/android/android_device.dart @@ -177,7 +177,7 @@ class AndroidDevice extends Device { } finally { console.destroy(); } - } catch (e) { + } on Exception catch (e) { globals.printTrace('Failed to fetch avd name for emulator at $host:$port: $e'); // If we fail to connect to the device, we should not fail so just return // an empty name. This data is best-effort. @@ -299,7 +299,7 @@ class AndroidDevice extends Device { return true; } globals.printError('The ADB at "${getAdbPath(androidSdk)}" is too old; please install version 1.0.39 or later.'); - } catch (error, trace) { + } on Exception catch (error, trace) { globals.printError('Error running ADB: $error', stackTrace: trace); } @@ -335,7 +335,7 @@ class AndroidDevice extends Device { } return true; - } catch (e, stacktrace) { + } on Exception catch (e, stacktrace) { globals.printError('Unexpected failure from adb: $e'); globals.printError('Stacktrace: $stacktrace'); return false; @@ -366,7 +366,7 @@ class AndroidDevice extends Device { try { final RunResult listOut = await runAdbCheckedAsync(['shell', 'pm', 'list', 'packages', app.id]); return LineSplitter.split(listOut.stdout).contains('package:${app.id}'); - } catch (error) { + } on Exception catch (error) { globals.printTrace('$error'); return false; } @@ -432,7 +432,7 @@ class AndroidDevice extends Device { throwOnError: true, ); uninstallOut = uninstallResult.stdout; - } catch (error) { + } on Exception catch (error) { globals.printError('adb uninstall failed: $error'); return false; } @@ -631,7 +631,7 @@ class AndroidDevice extends Device { } return LaunchResult.succeeded(observatoryUri: observatoryUri); - } catch (error) { + } on Exception catch (error) { globals.printError('Error waiting for a debug connection: $error'); return LaunchResult.failed(); } finally { @@ -696,7 +696,7 @@ class AndroidDevice extends Device { output = runAdbCheckedSync([ 'shell', '-x', 'logcat', '-v', 'time', '-t', '1' ]); - } catch (error) { + } on Exception catch (error) { globals.printError('Failed to extract the most recent timestamp from the Android log: $error.'); return null; } diff --git a/packages/flutter_tools/lib/src/android/android_sdk.dart b/packages/flutter_tools/lib/src/android/android_sdk.dart index bb4a429d289..567ff4634f0 100644 --- a/packages/flutter_tools/lib/src/android/android_sdk.dart +++ b/packages/flutter_tools/lib/src/android/android_sdk.dart @@ -492,7 +492,7 @@ class AndroidSdk { .map((FileSystemEntity entity) { try { return Version.parse(entity.basename); - } catch (error) { + } on Exception { return null; } }) @@ -518,7 +518,7 @@ class AndroidSdk { .group(1); platformVersion = int.parse(versionString); } - } catch (error) { + } on Exception { return null; } @@ -583,7 +583,7 @@ class AndroidSdk { return fileSystem.path.join(javaHome, 'bin', 'java'); } } - } catch (_) { /* ignore */ } + } on Exception catch (_) { /* ignore */ } } // Fallback to PATH based lookup. diff --git a/packages/flutter_tools/lib/src/android/android_studio.dart b/packages/flutter_tools/lib/src/android/android_studio.dart index 961b6738a0b..eb07945b2c8 100644 --- a/packages/flutter_tools/lib/src/android/android_studio.dart +++ b/packages/flutter_tools/lib/src/android/android_studio.dart @@ -93,7 +93,7 @@ class AndroidStudio implements Comparable { installPath = globals.fs .file(globals.fs.path.join(homeDotDir.path, 'system', '.home')) .readAsStringSync(); - } catch (e) { + } on Exception { // ignored, installPath will be null, which is handled below } if (installPath != null && globals.fs.isDirectorySync(installPath)) { @@ -200,7 +200,7 @@ class AndroidStudio implements Comparable { _checkForStudio(directory.path); } } - } catch (e) { + } on Exception catch (e) { globals.printTrace('Exception while looking for Android Studio: $e'); } } diff --git a/packages/flutter_tools/lib/src/android/android_workflow.dart b/packages/flutter_tools/lib/src/android/android_workflow.dart index 004392694d0..ef3d5fa2ff5 100644 --- a/packages/flutter_tools/lib/src/android/android_workflow.dart +++ b/packages/flutter_tools/lib/src/android/android_workflow.dart @@ -122,7 +122,7 @@ class AndroidValidator extends DoctorValidator { final List versionLines = (result.stderr as String).split('\n'); javaVersionText = versionLines.length >= 2 ? versionLines[1] : versionLines[0]; } - } catch (error) { + } on Exception catch (error) { _logger.printTrace(error.toString()); } if (javaVersionText == null || javaVersionText.isEmpty) { @@ -287,7 +287,7 @@ class AndroidLicenseValidator extends DoctorValidator { final List versionLines = (result.stderr as String).split('\n'); javaVersion = versionLines.length >= 2 ? versionLines[1] : versionLines[0]; } - } catch (error) { + } on Exception catch (error) { globals.printTrace(error.toString()); } if (javaVersion == null) { @@ -389,7 +389,7 @@ class AndroidLicenseValidator extends DoctorValidator { globals.stdio.addStdoutStream(process.stdout), globals.stdio.addStderrStream(process.stderr), ]); - } catch (err, stack) { + } on Exception catch (err, stack) { globals.printTrace('Echoing stdout or stderr from the license subprocess failed:'); globals.printTrace('$err\n$stack'); } diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart index fbc443f14a6..9cd290fe814 100644 --- a/packages/flutter_tools/lib/src/asset.dart +++ b/packages/flutter_tools/lib/src/asset.dart @@ -128,7 +128,7 @@ class _ManifestAssetBundle implements AssetBundle { FlutterManifest flutterManifest; try { flutterManifest = FlutterManifest.createFromPath(manifestPath); - } catch (e) { + } on Exception catch (e) { globals.printStatus('Error detected in pubspec.yaml:', emphasis: true); globals.printError('$e'); return 1; diff --git a/packages/flutter_tools/lib/src/base/async_guard.dart b/packages/flutter_tools/lib/src/base/async_guard.dart index 45151745cbc..d25cf58f681 100644 --- a/packages/flutter_tools/lib/src/base/async_guard.dart +++ b/packages/flutter_tools/lib/src/base/async_guard.dart @@ -112,7 +112,9 @@ Future asyncGuard( if (!completer.isCompleted) { completer.complete(result); } - } catch (e, s) { + // This catches all exceptions so that they can be propagated to the + // caller-supplied error handling or the completer. + } catch (e, s) { // ignore: avoid_catches_without_on_clauses handleError(e, s); } }, onError: (Object e, StackTrace s) { diff --git a/packages/flutter_tools/lib/src/base/fingerprint.dart b/packages/flutter_tools/lib/src/base/fingerprint.dart index 815acc27295..f20e10763b1 100644 --- a/packages/flutter_tools/lib/src/base/fingerprint.dart +++ b/packages/flutter_tools/lib/src/base/fingerprint.dart @@ -66,7 +66,7 @@ class Fingerprinter { final Fingerprint oldFingerprint = Fingerprint.fromJson(fingerprintFile.readAsStringSync()); final Fingerprint newFingerprint = buildFingerprint(); return oldFingerprint == newFingerprint; - } catch (e) { + } on Exception catch (e) { // Log exception and continue, fingerprinting is only a performance improvement. globals.printTrace('Fingerprint check error: $e'); } @@ -77,7 +77,7 @@ class Fingerprinter { try { final Fingerprint fingerprint = buildFingerprint(); globals.fs.file(fingerprintPath).writeAsStringSync(fingerprint.toJson()); - } catch (e) { + } on Exception catch (e) { // Log exception and continue, fingerprinting is only a performance improvement. globals.printTrace('Fingerprint write error: $e'); } @@ -103,7 +103,7 @@ class Fingerprint { final Iterable files = inputPaths.map(globals.fs.file); final Iterable missingInputs = files.where((File file) => !file.existsSync()); if (missingInputs.isNotEmpty) { - throw ArgumentError('Missing input files:\n' + missingInputs.join('\n')); + throw Exception('Missing input files:\n' + missingInputs.join('\n')); } _checksums = {}; @@ -116,14 +116,14 @@ class Fingerprint { /// Creates a Fingerprint from serialized JSON. /// - /// Throws [ArgumentError], if there is a version mismatch between the + /// Throws [Exception], if there is a version mismatch between the /// serializing framework and this framework. Fingerprint.fromJson(String jsonData) { final Map content = castStringKeyedMap(json.decode(jsonData)); final String version = content['version'] as String; if (version != globals.flutterVersion.frameworkRevision) { - throw ArgumentError('Incompatible fingerprint version: $version'); + throw Exception('Incompatible fingerprint version: $version'); } _checksums = castStringKeyedMap(content['files'])?.cast() ?? {}; _properties = castStringKeyedMap(content['properties'])?.cast() ?? {}; @@ -182,8 +182,11 @@ Set readDepfile(String depfilePath) { // outfile1 outfile2 : file1.dart file2.dart file3.dart final String contents = globals.fs.file(depfilePath).readAsStringSync(); - final String dependencies = contents.split(': ')[1]; - return dependencies + final List dependencies = contents.split(': '); + if (dependencies.length < 2) { + throw Exception('malformed depfile'); + } + return dependencies[1] .replaceAllMapped(_separatorExpr, (Match match) => '${match.group(1)}\n') .split('\n') .map((String path) => path.replaceAllMapped(_escapeExpr, (Match match) => match.group(1)).trim()) diff --git a/packages/flutter_tools/lib/src/base/logger.dart b/packages/flutter_tools/lib/src/base/logger.dart index 88256cad18c..0d9283311ff 100644 --- a/packages/flutter_tools/lib/src/base/logger.dart +++ b/packages/flutter_tools/lib/src/base/logger.dart @@ -365,7 +365,8 @@ class WindowsStdoutLogger extends StdoutLogger { ? message : message.replaceAll('🔥', '') .replaceAll('✗', 'X') - .replaceAll('✓', '√'); + .replaceAll('✓', '√') + .replaceAll('🔨', ''); _stdio.stdoutWrite(windowsMessage); } } diff --git a/packages/flutter_tools/lib/src/base/os.dart b/packages/flutter_tools/lib/src/base/os.dart index 65c8b5a7428..099a71fe8cb 100644 --- a/packages/flutter_tools/lib/src/base/os.dart +++ b/packages/flutter_tools/lib/src/base/os.dart @@ -136,7 +136,7 @@ abstract class OperatingSystemUtils { return findFreePort(ipv6: true); } _logger.printTrace('findFreePort failed: $e'); - } catch (e) { + } on Exception catch (e) { // Failures are signaled by a return value of 0 from this function. _logger.printTrace('findFreePort failed: $e'); } finally { diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart index d8b5d747c78..eddf2c5e4fe 100644 --- a/packages/flutter_tools/lib/src/base/process.dart +++ b/packages/flutter_tools/lib/src/base/process.dart @@ -367,7 +367,7 @@ class _DefaultProcessUtils implements ProcessUtils { stdioFuture = stdioFuture.timeout(const Duration(seconds: 1)); } await stdioFuture; - } catch (_) { + } on Exception catch (_) { // Ignore errors on the process' stdout and stderr streams. Just capture // whatever we got, and use the exit code } @@ -539,7 +539,7 @@ class _DefaultProcessUtils implements ProcessUtils { _traceCommand(cli); try { return _processManager.runSync(cli, environment: environment).exitCode == 0; - } catch (error) { + } on Exception catch (error) { _logger.printTrace('$cli failed with $error'); return false; } @@ -553,7 +553,7 @@ class _DefaultProcessUtils implements ProcessUtils { _traceCommand(cli); try { return (await _processManager.run(cli, environment: environment)).exitCode == 0; - } catch (error) { + } on Exception catch (error) { _logger.printTrace('$cli failed with $error'); return false; } diff --git a/packages/flutter_tools/lib/src/base/signals.dart b/packages/flutter_tools/lib/src/base/signals.dart index 28b9e67e866..dbbbd76dc99 100644 --- a/packages/flutter_tools/lib/src/base/signals.dart +++ b/packages/flutter_tools/lib/src/base/signals.dart @@ -117,7 +117,7 @@ class _DefaultSignals implements Signals { for (final SignalHandler handler in _handlersList[s]) { try { await asyncGuard(() async => handler(s)); - } catch (e) { + } on Exception catch (e) { if (_errorStreamController.hasListener) { _errorStreamController.add(e); } diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart index c777a6fa31c..cd86e413ea3 100644 --- a/packages/flutter_tools/lib/src/build_info.dart +++ b/packages/flutter_tools/lib/src/build_info.dart @@ -399,8 +399,7 @@ DarwinArch getIOSArchForName(String arch) { case 'x86_64': return DarwinArch.x86_64; } - assert(false); - return null; + throw Exception('Unsupported iOS arch name "$arch"'); } String getNameForTargetPlatform(TargetPlatform platform, {DarwinArch darwinArch}) { @@ -481,8 +480,7 @@ AndroidArch getAndroidArchForName(String platform) { case 'android-x86': return AndroidArch.x86; } - assert(false); - return null; + throw Exception('Unsupported Android arch name "$platform"'); } String getNameForAndroidArch(AndroidArch arch) { diff --git a/packages/flutter_tools/lib/src/build_system/build_system.dart b/packages/flutter_tools/lib/src/build_system/build_system.dart index 18c2e0fd8cc..3a27b5209aa 100644 --- a/packages/flutter_tools/lib/src/build_system/build_system.dart +++ b/packages/flutter_tools/lib/src/build_system/build_system.dart @@ -582,7 +582,7 @@ class _BuildInstance { previousFile.deleteSync(); } } - } catch (exception, stackTrace) { + } on Exception catch (exception, stackTrace) { // TODO(jonahwilliams): throw specific exception for expected errors to mark // as non-fatal. All others should be fatal. node.target.clearStamp(environment); diff --git a/packages/flutter_tools/lib/src/build_system/file_hash_store.dart b/packages/flutter_tools/lib/src/build_system/file_hash_store.dart index b1b679ec44f..ecd3d488ed8 100644 --- a/packages/flutter_tools/lib/src/build_system/file_hash_store.dart +++ b/packages/flutter_tools/lib/src/build_system/file_hash_store.dart @@ -115,8 +115,8 @@ class FileHashStore { FileStorage fileStorage; try { fileStorage = FileStorage.fromBuffer(data); - } catch (err) { - _logger.printTrace('Filestorage format changed'); + } on Exception catch (err) { + _logger.printTrace('Filestorage format changed: $err'); cacheFile.deleteSync(); return; } diff --git a/packages/flutter_tools/lib/src/build_system/targets/ios.dart b/packages/flutter_tools/lib/src/build_system/targets/ios.dart index 977aae1c6ec..990716cf8af 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/ios.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/ios.dart @@ -376,8 +376,8 @@ class ReleaseIosApplicationBundle extends IosAssetBundle { Future createStubAppFramework(File outputFile, SdkType sdk, { bool include32Bit = true }) async { try { outputFile.createSync(recursive: true); - } catch (e) { - throwToolExit('Failed to create App.framework stub at ${outputFile.path}'); + } on Exception catch (e) { + throwToolExit('Failed to create App.framework stub at ${outputFile.path}: $e'); } final Directory tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_stub_source.'); @@ -420,8 +420,8 @@ Future createStubAppFramework(File outputFile, SdkType sdk, { bool in tempDir.deleteSync(recursive: true); } on FileSystemException catch (_) { // Best effort. Sometimes we can't delete things from system temp. - } catch (e) { - throwToolExit('Failed to create App.framework stub at ${outputFile.path}'); + } on Exception catch (e) { + throwToolExit('Failed to create App.framework stub at ${outputFile.path}: $e'); } } } diff --git a/packages/flutter_tools/lib/src/build_system/targets/macos.dart b/packages/flutter_tools/lib/src/build_system/targets/macos.dart index c2b3531ae81..a4d5c9dfe34 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/macos.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/macos.dart @@ -331,7 +331,7 @@ abstract class MacOSBundleFlutterAssets extends Target { try { final File sourceFile = environment.buildDir.childFile('app.dill'); sourceFile.copySync(assetDirectory.childFile('kernel_blob.bin').path); - } catch (err) { + } on Exception catch (err) { throw Exception('Failed to copy app.dill: $err'); } // Copy precompiled runtimes. @@ -344,7 +344,7 @@ abstract class MacOSBundleFlutterAssets extends Target { assetDirectory.childFile('vm_snapshot_data').path); globals.fs.file(isolateSnapshotData).copySync( assetDirectory.childFile('isolate_snapshot_data').path); - } catch (err) { + } on Exception catch (err) { throw Exception('Failed to copy precompiled runtimes: $err'); } } diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart index bfbde09a9c0..34c59908f30 100644 --- a/packages/flutter_tools/lib/src/cache.dart +++ b/packages/flutter_tools/lib/src/cache.dart @@ -403,7 +403,7 @@ class Cache { if (!cachedFile.existsSync()) { try { await downloadFile(url, cachedFile); - } catch (e) { + } on Exception catch (e) { throwToolExit('Failed to fetch third-party artifact $url: $e'); } } @@ -597,7 +597,8 @@ abstract class CachedArtifact extends ArtifactSet { try { await cache.downloadFile(url, tempFile); status.stop(); - } catch (exception) { + // The exception is rethrown, so don't catch only Exceptions. + } catch (exception) { // ignore: avoid_catches_without_on_clauses status.cancel(); rethrow; } diff --git a/packages/flutter_tools/lib/src/commands/analyze_base.dart b/packages/flutter_tools/lib/src/commands/analyze_base.dart index 63fb3dce1d6..2190d802b1d 100644 --- a/packages/flutter_tools/lib/src/commands/analyze_base.dart +++ b/packages/flutter_tools/lib/src/commands/analyze_base.dart @@ -33,7 +33,7 @@ abstract class AnalyzeBase { } finally { resultsFile.close(); } - } catch (e) { + } on Exception catch (e) { globals.printError('Failed to save output to "${argResults['write']}": $e'); } } diff --git a/packages/flutter_tools/lib/src/commands/assemble.dart b/packages/flutter_tools/lib/src/commands/assemble.dart index 4dac90e60b8..4a0a018621f 100644 --- a/packages/flutter_tools/lib/src/commands/assemble.dart +++ b/packages/flutter_tools/lib/src/commands/assemble.dart @@ -104,7 +104,7 @@ class AssembleCommand extends FlutterCommand { CustomDimensions.commandBuildBundleTargetPlatform: localEnvironment.defines['TargetPlatform'], CustomDimensions.commandBuildBundleIsModule: '${futterProject.isModule}', }; - } catch (err) { + } on Exception { // We've failed to send usage. } return const {}; diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart index a1f8530d6ae..941ad3b6617 100644 --- a/packages/flutter_tools/lib/src/commands/attach.dart +++ b/packages/flutter_tools/lib/src/commands/attach.dart @@ -114,7 +114,7 @@ class AttachCommand extends FlutterCommand { } try { return int.parse(stringArg('debug-port')); - } catch (error) { + } on Exception catch (error) { throwToolExit('Invalid port for `--debug-port`: $error'); } return null; @@ -222,7 +222,7 @@ class AttachCommand extends FlutterCommand { try { isolateDiscoveryProtocol = device.getIsolateDiscoveryProtocol(module); observatoryUri = Stream.value(await isolateDiscoveryProtocol.uri).asBroadcastStream(); - } catch (_) { + } on Exception { isolateDiscoveryProtocol?.dispose(); final List ports = device.portForwarder.forwardedPorts.toList(); for (final ForwardedPort port in ports) { @@ -292,7 +292,7 @@ class AttachCommand extends FlutterCommand { globals.fs.currentDirectory, LaunchMode.attach, ); - } catch (error) { + } on Exception catch (error) { throwToolExit(error.toString()); } result = await app.runner.waitForAppToFinish(); diff --git a/packages/flutter_tools/lib/src/commands/clean.dart b/packages/flutter_tools/lib/src/commands/clean.dart index da967b0ebe0..a352261df4e 100644 --- a/packages/flutter_tools/lib/src/commands/clean.dart +++ b/packages/flutter_tools/lib/src/commands/clean.dart @@ -71,7 +71,7 @@ class CleanCommand extends FlutterCommand { for (final String scheme in projectInfo.schemes) { await xcodeProjectInterpreter.cleanWorkspace(xcodeWorkspace.path, scheme); } - } catch (error) { + } on Exception catch (error) { globals.printTrace('Could not clean Xcode workspace: $error'); } finally { xcodeStatus?.stop(); diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart index ea1c3c269be..6bb780e89ba 100644 --- a/packages/flutter_tools/lib/src/commands/create.dart +++ b/packages/flutter_tools/lib/src/commands/create.dart @@ -264,7 +264,7 @@ class CreateCommand extends FlutterCommand { outputFile.writeAsStringSync(samplesJson); globals.printStatus('Wrote samples JSON to "$outputFilePath"'); } - } catch (e) { + } on Exception catch (e) { throwToolExit('Failed to write samples JSON to "$outputFilePath": $e', exitCode: 2); } } diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart index 942716482f5..a7825f6da76 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart @@ -175,7 +175,7 @@ class Daemon { completer.complete(request['result']); } } - } catch (error, trace) { + } on Exception catch (error, trace) { _send({ 'id': id, 'error': _toJsonable(error), @@ -414,7 +414,7 @@ class DaemonDomain extends Domain { return { 'platforms': result, }; - } catch (err, stackTrace) { + } on Exception catch (err, stackTrace) { sendEvent('log', { 'log': 'Failed to parse project metadata', 'stackTrace': stackTrace.toString(), @@ -596,7 +596,7 @@ class AppDomain extends Domain { appStartedCompleter: appStartedCompleter, ); _sendAppEvent(app, 'stop'); - } catch (error, trace) { + } on Exception catch (error, trace) { _sendAppEvent(app, 'stop', { 'error': _toJsonable(error), 'trace': '$trace', @@ -780,7 +780,7 @@ class DeviceDomain extends Domain { try { final Map response = await _deviceToMap(device); sendEvent(eventName, response); - } catch (err) { + } on Exception catch (err) { globals.printError('$err'); } }); diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart index 6ea5281c56f..3b5fd1d6f19 100644 --- a/packages/flutter_tools/lib/src/commands/drive.dart +++ b/packages/flutter_tools/lib/src/commands/drive.dart @@ -261,7 +261,7 @@ $ex try { await window.setLocation(const math.Point(0, 0)); await window.setSize(math.Rectangle(0, 0, x, y)); - } catch (_) { + } on Exception { // Error might be thrown in some browsers. } @@ -278,7 +278,7 @@ $ex try { await testRunner([testFile], environment); - } catch (error, stackTrace) { + } on Exception catch (error, stackTrace) { if (error is ToolExit) { rethrow; } diff --git a/packages/flutter_tools/lib/src/commands/generate.dart b/packages/flutter_tools/lib/src/commands/generate.dart index 3f94441dcc1..c1241820d3c 100644 --- a/packages/flutter_tools/lib/src/commands/generate.dart +++ b/packages/flutter_tools/lib/src/commands/generate.dart @@ -52,8 +52,8 @@ class GenerateCommand extends FlutterCommand { globals.printError(stackData[0] as String); globals.printError(stackData[1] as String); globals.printError(StackTrace.fromString(stackData[2] as String).toString()); - } catch (err) { - globals.printError('Error reading error in ${errorFile.path}'); + } on Exception catch (err) { + globals.printError('Error reading error in ${errorFile.path}: $err'); } } return FlutterCommandResult.fail(); diff --git a/packages/flutter_tools/lib/src/commands/packages.dart b/packages/flutter_tools/lib/src/commands/packages.dart index b36fbf5b355..0a7e76b0a5c 100644 --- a/packages/flutter_tools/lib/src/commands/packages.dart +++ b/packages/flutter_tools/lib/src/commands/packages.dart @@ -98,7 +98,8 @@ class PackagesGetCommand extends FlutterCommand { ); pubGetTimer.stop(); flutterUsage.sendTiming('pub', 'get', pubGetTimer.elapsed, label: 'success'); - } catch (_) { + // Not limiting to catching Exception because the exception is rethrown. + } catch (_) { // ignore: avoid_catches_without_on_clauses pubGetTimer.stop(); flutterUsage.sendTiming('pub', 'get', pubGetTimer.elapsed, label: 'failure'); rethrow; diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index 15fa50a8831..0c3a8f0e7fd 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart @@ -420,7 +420,7 @@ class RunCommand extends RunCommandBase { dillOutputPath: stringArg('output-dill'), ipv6: ipv6, ); - } catch (error) { + } on Exception catch (error) { throwToolExit(error.toString()); } final DateTime appStartedTime = systemClock.now(); diff --git a/packages/flutter_tools/lib/src/commands/screenshot.dart b/packages/flutter_tools/lib/src/commands/screenshot.dart index a64d1ccfb2c..5d830e7fb3a 100644 --- a/packages/flutter_tools/lib/src/commands/screenshot.dart +++ b/packages/flutter_tools/lib/src/commands/screenshot.dart @@ -116,7 +116,7 @@ class ScreenshotCommand extends FlutterCommand { ); try { await device.takeScreenshot(outputFile); - } catch (error) { + } on Exception catch (error) { throwToolExit('Error taking screenshot: $error'); } _showOutputFileInfo(outputFile); diff --git a/packages/flutter_tools/lib/src/commands/unpack.dart b/packages/flutter_tools/lib/src/commands/unpack.dart index 07587d65306..885c4ddb0ad 100644 --- a/packages/flutter_tools/lib/src/commands/unpack.dart +++ b/packages/flutter_tools/lib/src/commands/unpack.dart @@ -150,7 +150,7 @@ class ArtifactUnpacker { } else { globals.printTrace('Artifacts for version $targetHash already present.'); } - } catch (error, stackTrace) { + } on Exception catch (error, stackTrace) { globals.printError(stackTrace.toString()); globals.printError(error.toString()); return false; @@ -200,8 +200,8 @@ class ArtifactUnpacker { } globals.printTrace('Copied artifacts from $sourceDirectory.'); - } catch (e, stackTrace) { - globals.printError(e.message as String); + } on Exception catch (e, stackTrace) { + globals.printError(e.toString()); globals.printError(stackTrace.toString()); return false; } diff --git a/packages/flutter_tools/lib/src/commands/upgrade.dart b/packages/flutter_tools/lib/src/commands/upgrade.dart index d423513b343..840e2655c91 100644 --- a/packages/flutter_tools/lib/src/commands/upgrade.dart +++ b/packages/flutter_tools/lib/src/commands/upgrade.dart @@ -210,7 +210,7 @@ class UpgradeCommandRunner { throwOnError: true, workingDirectory: workingDirectory, ); - } catch (e) { + } on Exception { throwToolExit( 'Unable to upgrade Flutter: no origin repository configured. ' "Run 'git remote add origin " @@ -279,7 +279,7 @@ class UpgradeCommandRunner { final FlutterVersion newFlutterVersion = FlutterVersion(const SystemClock(), workingDirectory); alreadyUpToDate = newFlutterVersion.channel == oldFlutterVersion.channel && newFlutterVersion.frameworkRevision == oldFlutterVersion.frameworkRevision; - } catch (e) { + } on Exception catch (e) { globals.printTrace('Failed to determine FlutterVersion after upgrade fast-forward: $e'); } return alreadyUpToDate; diff --git a/packages/flutter_tools/lib/src/commands/version.dart b/packages/flutter_tools/lib/src/commands/version.dart index 4d715a98879..b5fff3086a4 100644 --- a/packages/flutter_tools/lib/src/commands/version.dart +++ b/packages/flutter_tools/lib/src/commands/version.dart @@ -116,8 +116,8 @@ class VersionCommand extends FlutterCommand { throwOnError: true, workingDirectory: Cache.flutterRoot, ); - } catch (e) { - throwToolExit('Unable to checkout version branch for version $version.'); + } on Exception catch (e) { + throwToolExit('Unable to checkout version branch for version $version: $e'); } final FlutterVersion flutterVersion = FlutterVersion(); diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart index ff0ef4c7965..10ae1b92056 100644 --- a/packages/flutter_tools/lib/src/dart/pub.dart +++ b/packages/flutter_tools/lib/src/dart/pub.dart @@ -180,7 +180,8 @@ class _DefaultPub implements Pub { retry: true, ); status.stop(); - } catch (exception) { + // The exception is rethrown, so don't catch only Exceptions. + } catch (exception) { // ignore: avoid_catches_without_on_clauses status.cancel(); rethrow; } @@ -322,7 +323,7 @@ class _DefaultPub implements Pub { globals.stdio.addStdoutStream(process.stdout), globals.stdio.addStderrStream(process.stderr), ]); - } catch (err, stack) { + } on Exception catch (err, stack) { globals.printTrace('Echoing stdout or stderr from the pub subprocess failed:'); globals.printTrace('$err\n$stack'); } diff --git a/packages/flutter_tools/lib/src/desktop_device.dart b/packages/flutter_tools/lib/src/desktop_device.dart index 9250f5de9b2..fd3d0dfa659 100644 --- a/packages/flutter_tools/lib/src/desktop_device.dart +++ b/packages/flutter_tools/lib/src/desktop_device.dart @@ -116,7 +116,7 @@ abstract class DesktopDevice extends Device { final Uri observatoryUri = await observatoryDiscovery.uri; onAttached(package, buildMode, process); return LaunchResult.succeeded(observatoryUri: observatoryUri); - } catch (error) { + } on Exception catch (error) { globals.printError('Error waiting for a debug connection: $error'); return LaunchResult.failed(); } finally { diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart index b985bff325b..3a8be9530bf 100644 --- a/packages/flutter_tools/lib/src/devfs.dart +++ b/packages/flutter_tools/lib/src/devfs.dart @@ -238,7 +238,7 @@ class ServiceProtocolDevFSOperations implements DevFSOperations { List bytes; try { bytes = await content.contentsAsBytes(); - } catch (e) { + } on Exception catch (e) { return e; } final String fileContents = base64.encode(bytes); @@ -251,7 +251,7 @@ class ServiceProtocolDevFSOperations implements DevFSOperations { 'fileContents': fileContents, }, ); - } catch (error) { + } on Exception catch (error) { globals.printTrace('DevFS: Failed to write $deviceUri: $error'); } } @@ -319,7 +319,7 @@ class _DevFSHttpWriter { onError: (dynamic error) { globals.printTrace('error: $error'); }, cancelOnError: true); break; - } catch (error, trace) { + } on Exception catch (error, trace) { if (!_completer.isCompleted) { globals.printTrace('Error writing "$deviceUri" to DevFS: $error'); if (retry > 0) { @@ -527,7 +527,7 @@ class DevFS { } on SocketException catch (socketException, stackTrace) { globals.printTrace('DevFS sync failed. Lost connection to device: $socketException'); throw DevFSException('Lost connection to device.', socketException, stackTrace); - } catch (exception, stackTrace) { + } on Exception catch (exception, stackTrace) { globals.printError('Could not update files on device: $exception'); throw DevFSException('Sync failed', exception, stackTrace); } diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index 3a228fdd873..4a8ab5b3d07 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart @@ -198,7 +198,7 @@ class Doctor { ValidationResult result; try { result = await asyncGuard(() => validator.validate()); - } catch (exception) { + } on Exception catch (exception) { // We're generating a summary, so drop the stack trace. result = ValidationResult.crash(exception); } @@ -280,10 +280,10 @@ class Doctor { ValidationResult result; try { result = await validatorTask.result; - } catch (exception, stackTrace) { - result = ValidationResult.crash(exception, stackTrace); - } finally { status.stop(); + } on Exception catch (exception, stackTrace) { + result = ValidationResult.crash(exception, stackTrace); + status.cancel(); } switch (result.type) { @@ -437,7 +437,7 @@ class GroupedValidator extends DoctorValidator { _currentSlowWarning = subValidator.validator.slowWarning; try { results.add(await subValidator.result); - } catch (exception, stackTrace) { + } on Exception catch (exception, stackTrace) { results.add(ValidationResult.crash(exception, stackTrace)); } } @@ -667,7 +667,7 @@ bool _genSnapshotRuns(String genSnapshotPath) { const int kExpectedExitCode = 255; try { return processUtils.runSync([genSnapshotPath]).exitCode == kExpectedExitCode; - } catch (error) { + } on Exception { return false; } } @@ -795,7 +795,7 @@ class IntelliJValidatorOnLinuxAndWindows extends IntelliJValidator { String installPath; try { installPath = globals.fs.file(globals.fs.path.join(dir.path, 'system', '.home')).readAsStringSync(); - } catch (e) { + } on Exception { // ignored } if (installPath != null && globals.fs.isDirectorySync(installPath)) { diff --git a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart index 3efe09ad3be..9dfb52febb0 100644 --- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart +++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart @@ -271,7 +271,7 @@ class FuchsiaDevice extends Device { packageRepo.deleteSync(recursive: true); } packageRepo.createSync(recursive: true); - } catch (e) { + } on Exception catch (e) { globals.printError('Failed to create Fuchisa package repo directory ' 'at ${packageRepo.path}: $e'); return LaunchResult.failed(); @@ -384,7 +384,7 @@ class FuchsiaDevice extends Device { globals.printTrace("Removing the tool's package repo: at ${packageRepo.path}"); try { packageRepo.deleteSync(recursive: true); - } catch (e) { + } on Exception catch (e) { globals.printError('Failed to remove Fuchsia package repo directory ' 'at ${packageRepo.path}: $e.'); } @@ -467,9 +467,9 @@ class FuchsiaDevice extends Device { 'Failed to delete screenshot.ppm from the device:\n$deleteResult' ); } - } catch (_) { + } on Exception catch (e) { globals.printError( - 'Failed to delete screenshot.ppm from the device' + 'Failed to delete screenshot.ppm from the device: $e' ); } } diff --git a/packages/flutter_tools/lib/src/fuchsia/fuchsia_sdk.dart b/packages/flutter_tools/lib/src/fuchsia/fuchsia_sdk.dart index 628e624fb7e..59fc7389771 100644 --- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_sdk.dart +++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_sdk.dart @@ -92,7 +92,7 @@ class FuchsiaSdk { .transform(const LineSplitter())); }); return controller.stream; - } catch (exception) { + } on Exception catch (exception) { globals.printTrace('$exception'); } return const Stream.empty(); diff --git a/packages/flutter_tools/lib/src/intellij/intellij.dart b/packages/flutter_tools/lib/src/intellij/intellij.dart index 48a9a50d753..a976c0dd24f 100644 --- a/packages/flutter_tools/lib/src/intellij/intellij.dart +++ b/packages/flutter_tools/lib/src/intellij/intellij.dart @@ -67,7 +67,7 @@ class IntelliJPlugins { final int start = content.indexOf(versionStartTag); final int end = content.indexOf('', start); return content.substring(start + versionStartTag.length, end); - } catch (_) { + } on Exception { return null; } } diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart index 6cdea04a649..3d302923cca 100644 --- a/packages/flutter_tools/lib/src/ios/devices.dart +++ b/packages/flutter_tools/lib/src/ios/devices.dart @@ -448,7 +448,7 @@ String decodeSyslog(String line) { } } return utf8.decode(out); - } catch (_) { + } on Exception { // Unable to decode line: return as-is. return line; } diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index d9f8fe3b242..44a688b79e8 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart @@ -291,7 +291,7 @@ class IOSSimulator extends Device { final IOSApp iosApp = app; await SimControl.instance.install(id, iosApp.simulatorBundlePath); return true; - } catch (e) { + } on Exception { return false; } } @@ -301,7 +301,7 @@ class IOSSimulator extends Device { try { await SimControl.instance.uninstall(id, app.id); return true; - } catch (e) { + } on Exception { return false; } } @@ -395,7 +395,7 @@ class IOSSimulator extends Device { final String bundleIdentifier = globals.plistParser.getValueFromFile(plistPath, PlistParser.kCFBundleIdentifierKey); await SimControl.instance.launch(id, bundleIdentifier, args); - } catch (error) { + } on Exception catch (error) { globals.printError('$error'); return LaunchResult.failed(); } @@ -411,7 +411,7 @@ class IOSSimulator extends Device { try { final Uri deviceUri = await observatoryDiscovery.uri; return LaunchResult.succeeded(observatoryUri: deviceUri); - } catch (error) { + } on Exception catch (error) { globals.printError('Error waiting for a debug connection: $error'); return LaunchResult.failed(); } finally { diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart index dc9bbbb68c3..e5bc9dd98e9 100644 --- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart +++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart @@ -349,7 +349,7 @@ class XcodeProjectInterpreter { ); final String out = result.stdout.trim(); return parseXcodeBuildSettings(out); - } catch(error) { + } on Exception catch (error) { if (error is ProcessException && error.toString().contains('timed out')) { BuildEvent('xcode-show-build-settings-timeout', command: showBuildSettingsCommand.join(' '), diff --git a/packages/flutter_tools/lib/src/macos/xcode.dart b/packages/flutter_tools/lib/src/macos/xcode.dart index 55d22dc0d4e..936a5897bb4 100644 --- a/packages/flutter_tools/lib/src/macos/xcode.dart +++ b/packages/flutter_tools/lib/src/macos/xcode.dart @@ -406,11 +406,15 @@ class XCDevice { final String architecture = deviceProperties['architecture'] as String; try { cpuArchitecture = getIOSArchForName(architecture); - } catch (error) { - // Fallback to default iOS architecture. Future-proof against a theoretical version - // of Xcode that changes this string to something slightly different like "ARM64". + } on Exception { + // Fallback to default iOS architecture. Future-proof against a + // theoretical version of Xcode that changes this string to something + // slightly different like "ARM64". cpuArchitecture ??= defaultIOSArchs.first; - _logger.printError('Unknown architecture $architecture, defaulting to ${getNameForDarwinArch(cpuArchitecture)}'); + _logger.printError( + 'Unknown architecture $architecture, defaulting to ' + '${getNameForDarwinArch(cpuArchitecture)}', + ); } } return cpuArchitecture; diff --git a/packages/flutter_tools/lib/src/reporting/crash_reporting.dart b/packages/flutter_tools/lib/src/reporting/crash_reporting.dart index 466ba6341e5..1bffbf76d17 100644 --- a/packages/flutter_tools/lib/src/reporting/crash_reporting.dart +++ b/packages/flutter_tools/lib/src/reporting/crash_reporting.dart @@ -126,7 +126,9 @@ class CrashReportSender { } else { globals.printError('Failed to send crash report. Server responded with HTTP status code ${resp.statusCode}'); } - } catch (sendError, sendStackTrace) { + // Catch all exceptions to print the message that makes clear that the + // crash logger crashed. + } catch (sendError, sendStackTrace) { // ignore: avoid_catches_without_on_clauses if (sendError is SocketException || sendError is HttpException) { globals.printError('Failed to send crash report due to a network error: $sendError'); } else { diff --git a/packages/flutter_tools/lib/src/reporting/events.dart b/packages/flutter_tools/lib/src/reporting/events.dart index 3bf813905fc..46965509a78 100644 --- a/packages/flutter_tools/lib/src/reporting/events.dart +++ b/packages/flutter_tools/lib/src/reporting/events.dart @@ -195,7 +195,7 @@ class CommandResultEvent extends UsageEvent { label: parameter, value: maxRss, ); - } catch (error) { + } on Exception catch (error) { // If grabbing the maxRss fails for some reason, just don't send an event. globals.printTrace('Querying maxRss failed with error: $error'); } diff --git a/packages/flutter_tools/lib/src/reporting/github_template.dart b/packages/flutter_tools/lib/src/reporting/github_template.dart index f607a5b141e..5d958b765db 100644 --- a/packages/flutter_tools/lib/src/reporting/github_template.dart +++ b/packages/flutter_tools/lib/src/reporting/github_template.dart @@ -136,7 +136,7 @@ ${_projectMetadataInformation()} } else { globals.printTrace('Failed to shorten GitHub template URL. Server responded with HTTP status code ${response.statusCode}'); } - } catch (sendError) { + } on Exception catch (sendError) { globals.printTrace('Failed to shorten GitHub template URL: $sendError'); } diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index ab04d8245f8..69743986ea9 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -875,7 +875,7 @@ abstract class ResidentRunner { for (final FlutterView view in device.views) { await view.uiIsolate.flutterDebugAllowBanner(false); } - } catch (error) { + } on Exception catch (error) { status.cancel(); globals.printError('Error communicating with Flutter on the device: $error'); return; @@ -889,7 +889,7 @@ abstract class ResidentRunner { for (final FlutterView view in device.views) { await view.uiIsolate.flutterDebugAllowBanner(true); } - } catch (error) { + } on Exception catch (error) { status.cancel(); globals.printError('Error communicating with Flutter on the device: $error'); return; @@ -901,7 +901,7 @@ abstract class ResidentRunner { globals.printStatus( 'Screenshot written to ${globals.fs.path.relative(outputFile.path)} (${sizeKB}kB).', ); - } catch (error) { + } on Exception catch (error) { status.cancel(); globals.printError('Error taking screenshot: $error'); } @@ -1303,7 +1303,8 @@ class TerminalHandler { try { lastReceivedCommand = command; await _commonTerminalInputHandler(command); - } catch (error, st) { + // Catch all exception since this is doing cleanup and rethrowing. + } catch (error, st) { // ignore: avoid_catches_without_on_clauses // Don't print stack traces for known error types. if (error is! ToolExit) { globals.printError('$error\n$st'); diff --git a/packages/flutter_tools/lib/src/run_cold.dart b/packages/flutter_tools/lib/src/run_cold.dart index 6dbc7d6ffad..49387c18990 100644 --- a/packages/flutter_tools/lib/src/run_cold.dart +++ b/packages/flutter_tools/lib/src/run_cold.dart @@ -131,7 +131,7 @@ class ColdRunner extends ResidentRunner { _didAttach = true; try { await connectToServiceProtocol(); - } catch (error) { + } on Exception catch (error) { globals.printError('Error connecting to the service protocol: $error'); // https://github.com/flutter/flutter/issues/33050 // TODO(blasten): Remove this check once https://issuetracker.google.com/issues/132325318 has been fixed. diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index 95a4fb58301..ac645490690 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -186,7 +186,7 @@ class HotRunner extends ResidentRunner { final Map firstReport = reports.first; await device.updateReloadStatus(validateReloadReport(firstReport, printErrors: false)); } - } catch (error) { + } on Exception catch (error) { return OperationResult(1, error.toString()); } @@ -215,14 +215,25 @@ class HotRunner extends ResidentRunner { compileExpression: _compileExpressionService, reloadMethod: reloadMethod, ); - } catch (error) { + // Catches all exceptions, non-Exception objects are rethrown. + } catch (error) { // ignore: avoid_catches_without_on_clauses + if (error is! Exception && error is! String) { + rethrow; + } globals.printError('Error connecting to the service protocol: $error'); // https://github.com/flutter/flutter/issues/33050 - // TODO(blasten): Remove this check once https://issuetracker.google.com/issues/132325318 has been fixed. + // TODO(blasten): Remove this check once + // https://issuetracker.google.com/issues/132325318 has been fixed. if (await hasDeviceRunningAndroidQ(flutterDevices) && error.toString().contains(kAndroidQHttpConnectionClosedExp)) { - globals.printStatus('🔨 If you are using an emulator running Android Q Beta, consider using an emulator running API level 29 or lower.'); - globals.printStatus('Learn more about the status of this issue on https://issuetracker.google.com/issues/132325318.'); + globals.printStatus( + '🔨 If you are using an emulator running Android Q Beta, ' + 'consider using an emulator running API level 29 or lower.', + ); + globals.printStatus( + 'Learn more about the status of this issue on ' + 'https://issuetracker.google.com/issues/132325318.', + ); } return 2; } @@ -242,7 +253,7 @@ class HotRunner extends ResidentRunner { ), ); } - } catch (error) { + } on Exception catch (error) { globals.printError('Error initializing DevFS: $error'); return 3; } @@ -872,7 +883,7 @@ class HotRunner extends ResidentRunner { return OperationResult(errorCode, errorMessage); } return OperationResult(errorCode, '$errorMessage (error code: $errorCode)'); - } catch (error, stackTrace) { + } on Exception catch (error, stackTrace) { globals.printTrace('Hot reload failed: $error\n$stackTrace'); return OperationResult(1, '$error'); } @@ -936,7 +947,7 @@ class HotRunner extends ResidentRunner { () async { try { await view.uiIsolate.flutterReassemble(); - } catch (error) { + } on Exception catch (error) { failedReassemble = true; globals.printError('Reassembling ${view.uiIsolate.name} failed: $error'); return; diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart index 4ce44f36937..8342289ffd8 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart @@ -8,6 +8,7 @@ import 'package:args/args.dart'; import 'package:args/command_runner.dart'; import 'package:completion/completion.dart'; import 'package:file/file.dart'; +import 'package:meta/meta.dart'; import '../artifacts.dart'; import '../base/common.dart'; @@ -189,7 +190,7 @@ class FlutterCommandRunner extends CommandRunner { if (script.contains('flutter/examples/')) { return script.substring(0, script.indexOf('flutter/examples/') + 8); } - } catch (error) { + } on Exception catch (error) { // we don't have a logger at the time this is run // (which is why we don't use printTrace here) print(userMessages.runnerNoRoot('$error')); @@ -421,6 +422,7 @@ class FlutterCommandRunner extends CommandRunner { return EngineBuildPaths(targetEngine: engineBuildPath, hostEngine: engineHostBuildPath); } + @visibleForTesting static void initFlutterRoot() { Cache.flutterRoot ??= defaultFlutterRoot; } diff --git a/packages/flutter_tools/lib/src/test/flutter_platform.dart b/packages/flutter_tools/lib/src/test/flutter_platform.dart index 1e78e9e041a..025a4554691 100644 --- a/packages/flutter_tools/lib/src/test/flutter_platform.dart +++ b/packages/flutter_tools/lib/src/test/flutter_platform.dart @@ -313,7 +313,7 @@ class FlutterPlatform extends PlatformPlugin { final RunnerSuiteController controller = deserializeSuite(path, platform, suiteConfig, const PluginEnvironment(), channel, message); return await controller.suite; - } catch (err) { + } on Exception catch (err) { /// Rethrow a less confusing error if it is a test incompatibility. if (err.toString().contains("type 'Declarer' is not a subtype of type 'Declarer'")) { throw UnsupportedError('Package incompatibility between flutter and test packages:\n' @@ -667,7 +667,7 @@ class FlutterPlatform extends PlatformPlugin { } break; } - } catch (error, stack) { + } on Exception catch (error, stack) { globals.printTrace('test $ourTestCount: error caught during test; ${controllerSinkClosed ? "reporting to console" : "sending to test framework"}'); if (!controllerSinkClosed) { controller.sink.addError(error, stack); @@ -681,7 +681,7 @@ class FlutterPlatform extends PlatformPlugin { for (final Finalizer finalizer in finalizers.reversed) { try { await finalizer(); - } catch (error, stack) { + } on Exception catch (error, stack) { globals.printTrace('test $ourTestCount: error while cleaning up; ${controllerSinkClosed ? "reporting to console" : "sending to test framework"}'); if (!controllerSinkClosed) { controller.sink.addError(error, stack); @@ -873,7 +873,7 @@ class FlutterPlatform extends PlatformPlugin { if (reportObservatoryUri != null) { reportObservatoryUri(uri); } - } catch (error) { + } on Exception catch (error) { globals.printError('Could not parse shell observatory port message: $error'); } } else if (line != null) { diff --git a/packages/flutter_tools/lib/src/test/flutter_web_platform.dart b/packages/flutter_tools/lib/src/test/flutter_web_platform.dart index 93c26f7bd82..9434a45432b 100644 --- a/packages/flutter_tools/lib/src/test/flutter_web_platform.dart +++ b/packages/flutter_tools/lib/src/test/flutter_web_platform.dart @@ -743,7 +743,8 @@ class BrowserManager { _controllers.add(controller); return await controller.suite; - } catch (_) { + // Not limiting to catching Exception because the exception is rethrown. + } catch (_) { // ignore: avoid_catches_without_on_clauses closeIframe(); rethrow; } @@ -997,7 +998,7 @@ void main() async { try { bool success = await goldenFileComparator.compare(bytes, goldenKey); print(jsonEncode({'success': success})); - } catch (ex) { + } on Exception catch (ex) { print(jsonEncode({'success': false, 'message': '\$ex'})); } } diff --git a/packages/flutter_tools/lib/src/tester/flutter_tester.dart b/packages/flutter_tools/lib/src/tester/flutter_tester.dart index bd90c60aaaf..19cea0f645b 100644 --- a/packages/flutter_tools/lib/src/tester/flutter_tester.dart +++ b/packages/flutter_tools/lib/src/tester/flutter_tester.dart @@ -194,7 +194,7 @@ class FlutterTesterDevice extends Device { final Uri observatoryUri = await observatoryDiscovery.uri; return LaunchResult.succeeded(observatoryUri: observatoryUri); - } catch (error) { + } on Exception catch (error) { globals.printError('Failed to launch $package: $error'); return LaunchResult.failed(); } diff --git a/packages/flutter_tools/lib/src/tracing.dart b/packages/flutter_tools/lib/src/tracing.dart index 020d06816a7..25402b87693 100644 --- a/packages/flutter_tools/lib/src/tracing.dart +++ b/packages/flutter_tools/lib/src/tracing.dart @@ -60,7 +60,8 @@ class Tracing { if (!done) { await whenFirstFrameRendered.future; } - } catch (exception) { + // The exception is rethrown, so don't catch only Exceptions. + } catch (exception) { // ignore: avoid_catches_without_on_clauses status.cancel(); rethrow; } diff --git a/packages/flutter_tools/lib/src/version.dart b/packages/flutter_tools/lib/src/version.dart index 8a87986d93b..03ab5de2830 100644 --- a/packages/flutter_tools/lib/src/version.dart +++ b/packages/flutter_tools/lib/src/version.dart @@ -528,7 +528,7 @@ class VersionCheckStamp { } else { globals.printTrace('Warning: expected version stamp to be a Map but found: $jsonObject'); } - } catch (error, stackTrace) { + } on Exception catch (error, stackTrace) { // Do not crash if JSON is malformed. globals.printTrace('${error.runtimeType}: $error\n$stackTrace'); } diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart index f18f802772b..db9f7830c81 100644 --- a/packages/flutter_tools/lib/src/vmservice.dart +++ b/packages/flutter_tools/lib/src/vmservice.dart @@ -145,7 +145,7 @@ class VMService { return {'type': 'Success'}; } on rpc.RpcException { rethrow; - } catch (e, st) { + } on Exception catch (e, st) { throw rpc.RpcException(rpc_error_code.SERVER_ERROR, 'Error during Sources Reload: $e\n$st'); } @@ -189,7 +189,7 @@ class VMService { return {'type': 'Success'}; } on rpc.RpcException { rethrow; - } catch (e, st) { + } on Exception catch (e, st) { throw rpc.RpcException(rpc_error_code.SERVER_ERROR, 'Error during Sources Reload: $e\n$st'); } @@ -213,7 +213,7 @@ class VMService { return {'type': 'Success'}; } on rpc.RpcException { rethrow; - } catch (e, st) { + } on Exception catch (e, st) { throw rpc.RpcException(rpc_error_code.SERVER_ERROR, 'Error during Hot Restart: $e\n$st'); } @@ -266,7 +266,7 @@ class VMService { 'result': {'kernelBytes': kernelBytesBase64}}; } on rpc.RpcException { rethrow; - } catch (e, st) { + } on Exception catch (e, st) { throw rpc.RpcException(rpc_error_code.SERVER_ERROR, 'Error during expression compilation: $e\n$st'); } @@ -625,7 +625,8 @@ abstract class ServiceObject { updateFromMap(response); completer.complete(this); } - } catch (e, st) { + // Catches all exceptions to propagate to the completer. + } catch (e, st) { // ignore: avoid_catches_without_on_clauses completer.completeError(e, st); } _inProgressReload = null; diff --git a/packages/flutter_tools/lib/src/web/chrome.dart b/packages/flutter_tools/lib/src/web/chrome.dart index f28549647c7..19166dabf6d 100644 --- a/packages/flutter_tools/lib/src/web/chrome.dart +++ b/packages/flutter_tools/lib/src/web/chrome.dart @@ -211,7 +211,7 @@ class ChromeLauncher { if (!skipCheck) { try { await chrome.chromeConnection.getTabs(); - } catch (e) { + } on Exception catch (e) { await chrome.close(); throwToolExit( 'Unable to connect to Chrome debug port: ${chrome.debugPort}\n $e'); @@ -235,7 +235,7 @@ class ChromeLauncher { final HttpClientResponse response = await request.close(); final List jsonObject = await json.fuse(utf8).decoder.bind(response).single as List; return base.resolve(jsonObject.first['devtoolsFrontendUrl'] as String); - } catch (_) { + } on Exception { // If we fail to talk to the remote debugger protocol, give up and return // the raw URL rather than crashing. return base; diff --git a/packages/flutter_tools/lib/src/web/compile.dart b/packages/flutter_tools/lib/src/web/compile.dart index 15a1f6e05f8..e75471afaee 100644 --- a/packages/flutter_tools/lib/src/web/compile.dart +++ b/packages/flutter_tools/lib/src/web/compile.dart @@ -66,7 +66,7 @@ Future buildWeb( } throwToolExit('Failed to compile application for the Web.'); } - } catch (err) { + } on Exception catch (err) { throwToolExit(err.toString()); } finally { status.stop(); diff --git a/packages/flutter_tools/test/commands.shard/hermetic/assemble_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/assemble_test.dart index ceeedc10564..ad939557da7 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/assemble_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/assemble_test.dart @@ -7,6 +7,7 @@ import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/build_system/build_system.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/commands/assemble.dart'; +import 'package:flutter_tools/src/runner/flutter_command_runner.dart'; import 'package:mockito/mockito.dart'; import 'package:flutter_tools/src/globals.dart' as globals; @@ -15,6 +16,7 @@ import '../../src/context.dart'; import '../../src/testbed.dart'; void main() { + FlutterCommandRunner.initFlutterRoot(); Cache.disableLocking(); final Testbed testbed = Testbed(overrides: { BuildSystem: () => MockBuildSystem(), diff --git a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart index 51f018b13d6..75079c75cf8 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart @@ -76,7 +76,7 @@ void main() { '--show-test-device', ]); fail('Expect exception'); - } catch (e) { + } on Exception catch (e) { expect(e.toString(), isNot(contains('--fast-start is not supported with --use-application-binary'))); } }, overrides: { @@ -102,7 +102,7 @@ void main() { '--no-pub', ]); fail('Expect exception'); - } catch (e) { + } on Exception catch (e) { expect(e, isInstanceOf()); } final BufferLogger bufferLogger = globals.logger as BufferLogger; @@ -127,7 +127,7 @@ void main() { '--no-pub', ]); fail('Expect exception'); - } catch (e) { + } on Exception catch (e) { expect(e, isInstanceOf()); expect(e.toString(), contains('No pubspec.yaml file found')); } @@ -221,8 +221,8 @@ void main() { } on ToolExit catch (e) { // We expect a ToolExit because no devices are attached expect(e.message, null); - } catch (e) { - fail('ToolExit expected'); + } on Exception catch (e) { + fail('ToolExit expected, got $e'); } verifyInOrder([ @@ -293,8 +293,8 @@ void main() { } on ToolExit catch (e) { // We expect a ToolExit because app does not start expect(e.message, null); - } catch (e) { - fail('ToolExit expected'); + } on Exception catch (e) { + fail('ToolExit expected, got $e'); } final List captures = verify(mockUsage.sendCommand( captureAny, diff --git a/packages/flutter_tools/test/commands.shard/hermetic/version_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/version_test.dart index 482c3790038..972b433f0a2 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/version_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/version_test.dart @@ -163,7 +163,7 @@ void main() { try { await command.getTags(); fail('ToolExit expected'); - } catch(e) { + } on Exception catch (e) { expect(e, isA()); } }, overrides: { diff --git a/packages/flutter_tools/test/general.shard/android/android_device_test.dart b/packages/flutter_tools/test/general.shard/android/android_device_test.dart index 909762653d0..982550d6c11 100644 --- a/packages/flutter_tools/test/general.shard/android/android_device_test.dart +++ b/packages/flutter_tools/test/general.shard/android/android_device_test.dart @@ -584,7 +584,9 @@ flutter: final AndroidDevice device = AndroidDevice('emulator-5555'); expect(await device.emulatorId, isNull); }, overrides: { - AndroidConsoleSocketFactory: () => (String host, int port) => throw 'Fake socket error', + AndroidConsoleSocketFactory: () { + return (String host, int port) => throw Exception('Fake socket error'); + }, ProcessManager: () => mockProcessManager, }); diff --git a/packages/flutter_tools/test/general.shard/android/android_sdk_test.dart b/packages/flutter_tools/test/general.shard/android/android_sdk_test.dart index b1cfd66585c..8f12b4ee995 100644 --- a/packages/flutter_tools/test/general.shard/android/android_sdk_test.dart +++ b/packages/flutter_tools/test/general.shard/android/android_sdk_test.dart @@ -80,6 +80,13 @@ void main() { when(globals.processManager.runSync([sdk.sdkManagerPath, '--version'], environment: argThat(isNotNull, named: 'environment'))) .thenReturn(ProcessResult(1, 0, '26.1.1\n', '')); + if (globals.platform.isMacOS) { + when(globals.processManager.runSync( + ['/usr/libexec/java_home'], + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )).thenReturn(ProcessResult(0, 0, '', '')); + } expect(sdk.sdkManagerVersion, '26.1.1'); }, overrides: { FileSystem: () => fs, @@ -112,6 +119,13 @@ void main() { when(globals.processManager.runSync([sdk.sdkManagerPath, '--version'], environment: argThat(isNotNull, named: 'environment'))) .thenReturn(ProcessResult(1, 1, '26.1.1\n', 'Mystery error')); + if (globals.platform.isMacOS) { + when(globals.processManager.runSync( + ['/usr/libexec/java_home'], + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )).thenReturn(ProcessResult(0, 0, '', '')); + } expect(sdk.sdkManagerVersion, isNull); }, overrides: { FileSystem: () => fs, diff --git a/packages/flutter_tools/test/general.shard/asset_bundle_package_test.dart b/packages/flutter_tools/test/general.shard/asset_bundle_package_test.dart index e75dde645e5..515d1293f67 100644 --- a/packages/flutter_tools/test/general.shard/asset_bundle_package_test.dart +++ b/packages/flutter_tools/test/general.shard/asset_bundle_package_test.dart @@ -70,26 +70,32 @@ $assetsSection Future buildAndVerifyAssets( List assets, List packages, - String expectedAssetManifest, - ) async { + String expectedAssetManifest, { + bool expectExists = true, + }) async { final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); await bundle.build(manifestPath: 'pubspec.yaml'); for (final String packageName in packages) { for (final String asset in assets) { final String entryKey = Uri.encodeFull('packages/$packageName/$asset'); - expect(bundle.entries.containsKey(entryKey), true, reason: 'Cannot find key on bundle: $entryKey'); - expect( - utf8.decode(await bundle.entries[entryKey].contentsAsBytes()), - asset, - ); + expect(bundle.entries.containsKey(entryKey), expectExists, + reason: 'Cannot find key on bundle: $entryKey'); + if (expectExists) { + expect( + utf8.decode(await bundle.entries[entryKey].contentsAsBytes()), + asset, + ); + } } } - expect( - utf8.decode(await bundle.entries['AssetManifest.json'].contentsAsBytes()), - expectedAssetManifest, - ); + if (expectExists) { + expect( + utf8.decode(await bundle.entries['AssetManifest.json'].contentsAsBytes()), + expectedAssetManifest, + ); + } } void writeAssets(String path, List assets) { @@ -660,24 +666,15 @@ $assetsSection assets: assetOnManifest, ); - try { - await buildAndVerifyAssets( - assetOnManifest, - ['test_package'], - null, - ); - - final Function watchdog = () async { - assert(false, 'Code failed to detect missing directory. Test failed.'); - }; - watchdog(); - } catch (e) { - // Test successful - } + await buildAndVerifyAssets( + assetOnManifest, + ['test_package'], + null, + expectExists: false, + ); }, overrides: { FileSystem: () => testFileSystem, ProcessManager: () => FakeProcessManager.any(), }); - }); } diff --git a/packages/flutter_tools/test/general.shard/base/async_guard_test.dart b/packages/flutter_tools/test/general.shard/base/async_guard_test.dart index f0c46b72f6c..681d7eb5aec 100644 --- a/packages/flutter_tools/test/general.shard/base/async_guard_test.dart +++ b/packages/flutter_tools/test/general.shard/base/async_guard_test.dart @@ -197,7 +197,7 @@ void main() { ); try { await f; - } catch (e) { + } on String { caughtByHandler = true; } if (!completer.isCompleted) { @@ -235,7 +235,7 @@ void main() { ); try { await f; - } catch (e) { + } on String { caughtByHandler = true; } if (!completer.isCompleted) { @@ -275,7 +275,7 @@ void main() { ); try { await f; - } catch (e) { + } on String { caughtByHandler = true; } if (!completer.isCompleted) { diff --git a/packages/flutter_tools/test/general.shard/base/fingerprint_test.dart b/packages/flutter_tools/test/general.shard/base/fingerprint_test.dart index f57c970cd37..cef022ce2ed 100644 --- a/packages/flutter_tools/test/general.shard/base/fingerprint_test.dart +++ b/packages/flutter_tools/test/general.shard/base/fingerprint_test.dart @@ -249,7 +249,7 @@ void main() { globals.fs.file('a.dart').createSync(); expect( () => Fingerprint.fromBuildInputs({}, ['a.dart', 'b.dart']), - throwsArgumentError, + throwsException, ); }, overrides: { FileSystem: () => fs, @@ -328,7 +328,7 @@ void main() { 'properties': {}, 'files': {}, }); - expect(() => Fingerprint.fromJson(jsonString), throwsArgumentError); + expect(() => Fingerprint.fromJson(jsonString), throwsException); }, overrides: { FlutterVersion: () => mockVersion, }); @@ -338,7 +338,7 @@ void main() { 'properties': {}, 'files': {}, }); - expect(() => Fingerprint.fromJson(jsonString), throwsArgumentError); + expect(() => Fingerprint.fromJson(jsonString), throwsException); }, overrides: { FlutterVersion: () => mockVersion, }); diff --git a/packages/flutter_tools/test/general.shard/base/signals_test.dart b/packages/flutter_tools/test/general.shard/base/signals_test.dart index a3369d6d81d..3c7f9f2ab8f 100644 --- a/packages/flutter_tools/test/general.shard/base/signals_test.dart +++ b/packages/flutter_tools/test/general.shard/base/signals_test.dart @@ -61,8 +61,9 @@ void main() { }); testUsingContext('signal handler error goes on error stream', () async { + final Exception exn = Exception('Error'); signals.addHandler(signalUnderTest, (ProcessSignal s) { - throw 'Error'; + throw exn; }); final Completer completer = Completer(); @@ -75,7 +76,7 @@ void main() { controller.add(mockSignal); await completer.future; await errSub.cancel(); - expect(errList, ['Error']); + expect(errList, contains(exn)); }, overrides: { Signals: () => Signals(), }); diff --git a/packages/flutter_tools/test/general.shard/build_info_test.dart b/packages/flutter_tools/test/general.shard/build_info_test.dart index 6bff476b371..6fdd1692045 100644 --- a/packages/flutter_tools/test/general.shard/build_info_test.dart +++ b/packages/flutter_tools/test/general.shard/build_info_test.dart @@ -91,6 +91,6 @@ void main() { expect(getIOSArchForName('arm64'), DarwinArch.arm64); expect(getIOSArchForName('arm64e'), DarwinArch.arm64); expect(getIOSArchForName('x86_64'), DarwinArch.x86_64); - expect(() => getIOSArchForName('bogus'), throwsAssertionError); + expect(() => getIOSArchForName('bogus'), throwsException); }); } diff --git a/packages/flutter_tools/test/general.shard/cache_test.dart b/packages/flutter_tools/test/general.shard/cache_test.dart index 2c29c7ed741..7af793fb2c1 100644 --- a/packages/flutter_tools/test/general.shard/cache_test.dart +++ b/packages/flutter_tools/test/general.shard/cache_test.dart @@ -231,7 +231,7 @@ void main() { null, }); fail('Mock thrown exception expected'); - } catch (e) { + } on Exception { verify(artifact1.update()); // Don't continue when retrieval fails. verifyNever(artifact2.update()); diff --git a/packages/flutter_tools/test/general.shard/commands/build_apk_test.dart b/packages/flutter_tools/test/general.shard/commands/build_apk_test.dart index 561915582b8..bd0ae541894 100644 --- a/packages/flutter_tools/test/general.shard/commands/build_apk_test.dart +++ b/packages/flutter_tools/test/general.shard/commands/build_apk_test.dart @@ -152,6 +152,26 @@ void main() { .thenAnswer((_) => Future.value(process)); when(mockProcessManager.canRun(any)).thenReturn(false); + when(mockProcessManager.runSync( + argThat(contains(contains('gen_snapshot'))), + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )).thenReturn(ProcessResult(0, 255, '', '')); + + when(mockProcessManager.runSync( + ['/usr/bin/xcode-select', '--print-path'], + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )).thenReturn(ProcessResult(0, 0, '', '')); + + when(mockProcessManager.run( + ['which', 'pod'], + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )).thenAnswer((_) { + return Future.value(ProcessResult(0, 0, '', '')); + }); + mockAndroidSdk = MockAndroidSdk(); when(mockAndroidSdk.directory).thenReturn('irrelevant'); }); diff --git a/packages/flutter_tools/test/general.shard/commands/build_appbundle_test.dart b/packages/flutter_tools/test/general.shard/commands/build_appbundle_test.dart index 1fc1a70e1cb..83f54bddf4d 100644 --- a/packages/flutter_tools/test/general.shard/commands/build_appbundle_test.dart +++ b/packages/flutter_tools/test/general.shard/commands/build_appbundle_test.dart @@ -9,12 +9,11 @@ import 'package:flutter_tools/src/android/android_builder.dart'; import 'package:flutter_tools/src/android/android_sdk.dart'; import 'package:flutter_tools/src/base/context.dart'; import 'package:flutter_tools/src/base/file_system.dart'; - import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/commands/build_appbundle.dart'; +import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; -import 'package:flutter_tools/src/globals.dart' as globals; import 'package:mockito/mockito.dart'; import 'package:process/process.dart'; @@ -135,6 +134,26 @@ void main() { .thenAnswer((_) => Future.value(process)); when(mockProcessManager.canRun(any)).thenReturn(false); + when(mockProcessManager.runSync( + argThat(contains(contains('gen_snapshot'))), + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )).thenReturn(ProcessResult(0, 255, '', '')); + + when(mockProcessManager.runSync( + ['/usr/bin/xcode-select', '--print-path'], + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )).thenReturn(ProcessResult(0, 0, '', '')); + + when(mockProcessManager.run( + ['which', 'pod'], + workingDirectory: anyNamed('workingDirectory'), + environment: anyNamed('environment'), + )).thenAnswer((_) { + return Future.value(ProcessResult(0, 0, '', '')); + }); + mockAndroidSdk = MockAndroidSdk(); when(mockAndroidSdk.validateSdkWellFormed()).thenReturn(const []); when(mockAndroidSdk.directory).thenReturn('irrelevant'); diff --git a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart index cd51b1512ac..093008bf4c9 100644 --- a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart +++ b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart @@ -327,8 +327,7 @@ void main() { try { await pub.get(context: PubContext.flutterTests, checkLastModified: true); expect(true, isFalse, reason: 'pub.get did not throw'); - } catch (error) { - expect(error, isA()); + } on ToolExit catch (error) { expect(error.message, '/: unexpected concurrent modification of pubspec.yaml while running pub.'); } expect(testLogger.statusText, 'Running "flutter pub get" in /...\n'); diff --git a/packages/flutter_tools/test/general.shard/devfs_test.dart b/packages/flutter_tools/test/general.shard/devfs_test.dart index ce6e0e55e60..e09934e4c48 100644 --- a/packages/flutter_tools/test/general.shard/devfs_test.dart +++ b/packages/flutter_tools/test/general.shard/devfs_test.dart @@ -136,7 +136,7 @@ void main() { const int kFailedAttempts = 5; when(httpRequest.close()).thenAnswer((Invocation invocation) { if (nRequest++ < kFailedAttempts) { - throw 'Connection resert by peer'; + throw Exception('Connection resert by peer'); } return Future.value(httpClientResponse); }); diff --git a/packages/flutter_tools/test/general.shard/flutter_platform_test.dart b/packages/flutter_tools/test/general.shard/flutter_platform_test.dart index 13ef1afe95b..6a0a98bd5e5 100644 --- a/packages/flutter_tools/test/general.shard/flutter_platform_test.dart +++ b/packages/flutter_tools/test/general.shard/flutter_platform_test.dart @@ -46,8 +46,17 @@ void main() { Future> captureEnvironment() async { flutterPlatform.loadChannel('test1.dart', MockSuitePlatform()); + when(mockProcessManager.start( + any, + environment: anyNamed('environment')), + ).thenAnswer((_) { + return Future.value(MockProcess()); + }); await untilCalled(mockProcessManager.start(any, environment: anyNamed('environment'))); - final VerificationResult toVerify = verify(mockProcessManager.start(any, environment: captureAnyNamed('environment'))); + final VerificationResult toVerify = verify(mockProcessManager.start( + any, + environment: captureAnyNamed('environment'), + )); expect(toVerify.captured, hasLength(1)); expect(toVerify.captured.first, isA>()); return toVerify.captured.first as Map; @@ -146,6 +155,8 @@ class MockSuitePlatform extends Mock implements SuitePlatform {} class MockProcessManager extends Mock implements ProcessManager {} +class MockProcess extends Mock implements Process {} + class MockPlatform extends Mock implements Platform {} class MockHttpServer extends Mock implements HttpServer {} diff --git a/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart b/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart index 66b6922f8da..1f48f0b85f1 100644 --- a/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart +++ b/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart @@ -476,7 +476,7 @@ void main() { try { await device.takeScreenshot(globals.fs.file('file.ppm')); - } catch (_) { + } on Exception { assert(false); } expect( @@ -534,8 +534,8 @@ void main() { try { await device.takeScreenshot(globals.fs.file('file.ppm')); - } catch (_) { - assert(false); + } on Exception catch (e) { + fail('Unexpected exception: $e'); } }, overrides: { ProcessManager: () => mockProcessManager, diff --git a/packages/flutter_tools/test/general.shard/ios/code_signing_test.dart b/packages/flutter_tools/test/general.shard/ios/code_signing_test.dart index 7fc9fd0c322..f00d5aa77be 100644 --- a/packages/flutter_tools/test/general.shard/ios/code_signing_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/code_signing_test.dart @@ -229,9 +229,9 @@ void main() { Map signingConfigs; try { signingConfigs = await getCodeSigningIdentityDevelopmentTeam(iosApp: app); - } catch (e) { + } on Exception catch (e) { // This should not throw - expect(true, false); + fail('Code signing threw: $e'); } expect(testLogger.statusText, contains('Apple Development: Profile 1 (1111AAAA11)')); diff --git a/packages/flutter_tools/test/general.shard/ios/simulators_test.dart b/packages/flutter_tools/test/general.shard/ios/simulators_test.dart index 441058c68ee..1bfb6e0846b 100644 --- a/packages/flutter_tools/test/general.shard/ios/simulators_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/simulators_test.dart @@ -54,7 +54,7 @@ void main() { expect(portForwarder.forwardedPorts.length, 2); try { await portForwarder.dispose(); - } catch (e) { + } on Exception catch (e) { fail('Encountered exception: $e'); } expect(portForwarder.forwardedPorts.length, 0); diff --git a/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart b/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart index d712f7f1b50..979ce040a4b 100644 --- a/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart +++ b/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart @@ -387,7 +387,7 @@ void main() { engineDir: 'engine/path', ); fail('ToolExit expected'); - } catch(e) { + } on Exception catch (e) { expect(e, isA()); verifyNever(mockProcessManager.run( argThat(containsAllInOrder(['pod', 'install'])), @@ -436,7 +436,7 @@ Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by engineDir: 'engine/path', ); fail('ToolExit expected'); - } catch (e) { + } on Exception catch (e) { expect(e, isA()); expect( testLogger.errorText, diff --git a/packages/flutter_tools/test/integration.shard/test_driver.dart b/packages/flutter_tools/test/integration.shard/test_driver.dart index d361d16b99c..586d9eb99b8 100644 --- a/packages/flutter_tools/test/integration.shard/test_driver.dart +++ b/packages/flutter_tools/test/integration.shard/test_driver.dart @@ -528,7 +528,7 @@ class FlutterRunTestDriver extends FlutterTestDriver { // have already completed. _currentRunningAppId = (await started)['params']['appId'] as String; prematureExitGuard.complete(); - } catch (error, stackTrace) { + } on Exception catch (error, stackTrace) { prematureExitGuard.completeError(error, stackTrace); } }()); @@ -732,7 +732,7 @@ class FlutterTestTestDriver extends FlutterTestDriver { Map _parseJsonResponse(String line) { try { return castStringKeyedMap(json.decode(line)); - } catch (e) { + } on Exception { // Not valid JSON, so likely some other output. return null; } @@ -771,7 +771,7 @@ Map parseFlutterResponse(String line) { try { final Map response = castStringKeyedMap(json.decode(line)[0]); return response; - } catch (e) { + } on Exception { // Not valid JSON, so likely some other output that was surrounded by [brackets] return null; } diff --git a/packages/flutter_tools/test/src/common.dart b/packages/flutter_tools/test/src/common.dart index fb446bc744e..763c9db361b 100644 --- a/packages/flutter_tools/test/src/common.dart +++ b/packages/flutter_tools/test/src/common.dart @@ -139,7 +139,8 @@ Future expectToolExitLater(Future future, Matcher messageMatcher) fail('ToolExit expected, but nothing thrown'); } on ToolExit catch(e) { expect(e.message, messageMatcher); - } catch(e, trace) { + // Catch all exceptions to give a better test failure message. + } catch (e, trace) { // ignore: avoid_catches_without_on_clauses fail('ToolExit expected, got $e\n$trace'); } } diff --git a/packages/flutter_tools/test/src/context.dart b/packages/flutter_tools/test/src/context.dart index cc211051aa6..868f5a6d60d 100644 --- a/packages/flutter_tools/test/src/context.dart +++ b/packages/flutter_tools/test/src/context.dart @@ -151,7 +151,8 @@ void testUsingContext( return await testMethod(); }, ); - } catch (error) { + // This catch rethrows, so doesn't need to catch only Exception. + } catch (error) { // ignore: avoid_catches_without_on_clauses _printBufferedErrors(context); rethrow; } diff --git a/packages/flutter_tools/test/src/mocks.dart b/packages/flutter_tools/test/src/mocks.dart index dc6bab5776d..08c3c77315b 100644 --- a/packages/flutter_tools/test/src/mocks.dart +++ b/packages/flutter_tools/test/src/mocks.dart @@ -398,7 +398,8 @@ class MemoryIOSink implements IOSink { (List data) { try { add(data); - } catch (err, stack) { + // Catches all exceptions to propagate them to the completer. + } catch (err, stack) { // ignore: avoid_catches_without_on_clauses sub.cancel(); completer.completeError(err, stack); } diff --git a/packages/flutter_tools/tool/tool_coverage.dart b/packages/flutter_tools/tool/tool_coverage.dart index 9f1816dbee2..3fb65d0f84e 100644 --- a/packages/flutter_tools/tool/tool_coverage.dart +++ b/packages/flutter_tools/tool/tool_coverage.dart @@ -73,7 +73,8 @@ class VMPlatform extends PlatformPlugin { Isolate isolate; try { isolate = await _spawnIsolate(codePath, receivePort.sendPort); - } catch (error) { + // This catch rethrows, so doesn't need to catch only Exception. + } catch (error) { // ignore: avoid_catches_without_on_clauses receivePort.close(); rethrow; }