-
Notifications
You must be signed in to change notification settings - Fork 26
fix(webserver): refuse to boot when a fixed port is already bound - #799
Open
ChampionDesigns wants to merge 1 commit into
Open
fix(webserver): refuse to boot when a fixed port is already bound #799ChampionDesigns wants to merge 1 commit into
ChampionDesigns wants to merge 1 commit into
Conversation
startWebServer binds two fixed ports: 8080 for the REST and WebSocket API, and
4001 for the API docs. main() wrapped the call in a bare catch that logged
"failed to start web server" and carried on, so a bind failure left the app
running with no API at all.
That failure is close to invisible. The WebUI binds an ephemeral port and is
unaffected, so the skin still loads and the app looks normal; only every REST
call and every WebSocket behind it is gone. BootTiming.mark('webserver_up')
fires either way. The user sees an app that opened correctly and then
misbehaves, with the reason only in the log.
Two Decaid-family apps installed on one device share those fixed ports, so the
common cause is that the other one is already running.
- serveOrReportPortInUse raises a typed WebServerPortInUse for EADDRINUSE and
rethrows every other failure unchanged, so a permission denial keeps its own
error path and is never reported to the user as a port clash.
- isAddressInUse matches the OS code per platform -- 98 on Linux and Android,
48 on macOS and iOS, 10048 on Windows -- because Dart reports the raw code
and does not normalise it.
- main() stops on WebServerPortInUse and shows a screen naming the port instead
of booting without an API.
The screen offers "Check again", which re-probes the port, and "Close this app".
It does not try to close the other app: Android does not let one app stop
another, and killBackgroundProcesses needs its own permission and only ever
touches background processes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The app could boot with no API at all and say nothing.
startWebServerbinds two fixed ports: 8080 for the REST and WebSocket API, and 4001 for the APIdocs.
main()wrapped the call in a bare catch that logged "failed to start web server" andcarried on.
That failure is close to invisible. The WebUI binds an ephemeral port and is unaffected, so the
skin still loads and the app looks normal — only every REST call and every WebSocket behind it is
gone.
BootTiming.mark('webserver_up')fires either way. The user sees an app that openedcorrectly and then misbehaves, with the reason only in the log.
Two Decaid-family apps installed on one device share those fixed ports, so the common cause is
simply that the other one is already running.
Base:
main. Independent.Design notes
serveOrReportPortInUseraises a typedWebServerPortInUseforEADDRINUSEand rethrowsevery other failure unchanged, so a permission denial keeps its own error path and is never
reported to the user as a port clash.
isAddressInUsematches the OS code per platform — 98 on Linux and Android, 48 on macOS andiOS, 10048 on Windows — because Dart reports the raw code and does not normalise it.
main()stops onWebServerPortInUseand shows a screen naming the port, offering "Check again"and "Close this app".
Linked Issue
N/A
Verification
flutter analyze— clean.flutter test— full suite 3904 passed against currentmain, includingport_binding_testandwebserver_port_conflict_app_test.dart format— clean on every changed file.machine, and has been exercised in normal use rather than only under test.
Impact
without an API. That is a deliberate behaviour change.
fails.
Contributor Responsibility
AI-assisted development is allowed. The submitter remains responsible for the submitted work.