Strip fx call-chain noise from startup errors; clarify file:// error

This commit is contained in:
2026-06-17 03:58:50 +02:00
parent 6e6e107243
commit 8de8f8e5cc
3 changed files with 60 additions and 3 deletions

View File

@@ -7,6 +7,7 @@ import (
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"
"time"
@@ -68,6 +69,24 @@ func NewApp(opts AppOptions) *fx.App {
return fx.New(allOptions...)
}
// cleanStartupError strips fx's dependency-injection call-chain noise from
// startup errors. fx wraps the underlying error with messages like
//
// could not build arguments for function "X" (file:line): failed to build T:
// could not build arguments for function "Y" (file:line): failed to build U:
// received non-nil error from function "Z" (file:line): <real error>
//
// Users care about the real error, not the DI plumbing. We strip everything
// up through the last "): " (which is always the close-paren of an fx
// function-location annotation followed by the wrapped error).
func cleanStartupError(err error) error {
msg := err.Error()
if idx := strings.LastIndex(msg, "): "); idx >= 0 {
msg = msg[idx+3:]
}
return errors.New(msg)
}
// RunApp starts and stops the fx application within the given context.
// It handles graceful shutdown on interrupt signals (SIGINT, SIGTERM) and
// ensures the application stops cleanly. The function blocks until the
@@ -83,7 +102,7 @@ func RunApp(ctx context.Context, app *fx.App) error {
// Start the app
if err := app.Start(ctx); err != nil {
return fmt.Errorf("failed to start app: %w", err)
return cleanStartupError(err)
}
// Handle shutdown