The installer's codebase contains several patterns that go against Go best practices, leading to poor error recovery and difficult debugging.
Identified Problems:
1. Misuse of os.Exit(1) in Library Packages
- Packages like
config and docker call os.Exit(1) directly when an error occurs (e.g., in GetConfig and GetStackConfig).
- Impact: This prevents the caller (like
main.go) from handling errors gracefully or performing cleanup. It also makes testing extremely difficult as the test runner will exit.
2. Excessive Use of Global State
- The project relies heavily on global variables and
sync.Once for singletons that maintain mutable state (e.g., config.ConnectedToInternet).
- Impact: This creates "hidden" dependencies between packages and makes the execution flow hard to follow and reason about.
3. Poor Error Wrapping and Context
- Many errors are returned without additional context or are logged to stdout instead of being wrapped.
- Impact: Difficulties in identifying the root cause of failures during installation.
4. Unmanaged Goroutines
- In
install.go, updater.MonitorConnection is launched as a goroutine without a context.Context or a way to stop it.
- Impact: Potential goroutine leaks and race conditions if the installation is cancelled or restarted.
Recommended Actions:
- Replace
os.Exit(1) calls with returning error in all non-main packages.
- Move initialization logic to a dedicated
Initialize function called from main.
- Pass context to goroutines and ensure they can be shut down gracefully.
- Use error wrapping (
fmt.Errorf("...: %w", err)) to provide better context.
The installer's codebase contains several patterns that go against Go best practices, leading to poor error recovery and difficult debugging.
Identified Problems:
1. Misuse of
os.Exit(1)in Library Packagesconfiganddockercallos.Exit(1)directly when an error occurs (e.g., inGetConfigandGetStackConfig).main.go) from handling errors gracefully or performing cleanup. It also makes testing extremely difficult as the test runner will exit.2. Excessive Use of Global State
sync.Oncefor singletons that maintain mutable state (e.g.,config.ConnectedToInternet).3. Poor Error Wrapping and Context
4. Unmanaged Goroutines
install.go,updater.MonitorConnectionis launched as a goroutine without acontext.Contextor a way to stop it.Recommended Actions:
os.Exit(1)calls with returningerrorin all non-main packages.Initializefunction called frommain.fmt.Errorf("...: %w", err)) to provide better context.