Skip to content

[ios][tools] xcode_backend.dart incorrectly calls exit rather than exitApp due to a design flaw #173138

@hellohuanlin

Description

@hellohuanlin

There's a problem with this code:

if (arguments.isEmpty) {
// Named entry points were introduced in Flutter v0.0.7.
echoXcodeError(incompatibleErrorMessage);
exit(-1);
}

Rather than calling exit(-1) directly, it should instead call the wrapper exitApp(-1):

Never exitApp(int code) {
exit(code);
}

The subclass TestContext overwrites exitApp to throw an exception:

Never exitApp(int code) {
// This is an exception for the benefit of unit tests.
// The real implementation calls `exit(code)`.
throw Exception('App exited with code $code');
}

So calling exit(-1) directly would terminate the test process directly, rather than throwing an exception.

Solution

short term

Replace exit with exitApp

Long term

This is another drawback of the current design using inheritance (see discussion #173133). It's too easy to introduce bugs like this if we keep this design.

Instead, we should inject an abstraction layer, say "Host":

// excuse my poor dart syntax, but you get the idea
abstract class Host {
  Never exit(int code);
  // other members like stdout/stderr
}

class RealHost: Host {
  Never exit(int code) {
    dart.io.exit(code);
  }
}

class FakeHost: Host {
  Never exit(int code) {
    throw Exception...
  }
}

Then xcode_backend.dart should just depend on the Host abstraction layer, without importing dart.io package.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listplatform-iosiOS applications specificallyteam-iosOwned by iOS platform teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-iosTriaged by iOS platform team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions