Print a startup or shutdown error once, without fx's event log (closes #359)
check / check (push) Successful in 1m51s
check / check (push) Successful in 1m51s
pixad builds its fx app with fx.NopLogger and runs start, wait and stop itself, so that it can print a start or stop error to stderr once. dig.RootCause strips the frames fx and dig wrap around the error, which leaves the line that names the setting. The exit status is as before. Two tests run runApp on a small fx app. A stop hook that fails has its error printed once, with exit status 1. A shutdown request's exit code is returned. Model: opus-5-5
This commit is contained in:
1 parent
8aaf6dc794
commit
2679139492
3 files changed
+109
-3
No files matched your search
@@ -0,0 +1,65 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
var errTestStopFailed = errors.New("test stop hook failed")
|
||||
|
||||
// TestRunAppPrintsStopErrorOnce checks that when a stop hook fails, runApp
|
||||
// prints the hook's error once and returns exit status 1.
|
||||
func TestRunAppPrintsStopErrorOnce(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app := fx.New(
|
||||
fx.NopLogger,
|
||||
fx.Invoke(func(lifecycle fx.Lifecycle, shutdowner fx.Shutdowner) {
|
||||
lifecycle.Append(fx.Hook{
|
||||
// Ask to shut down as soon as the app has started, so
|
||||
// that runApp goes on to stop it.
|
||||
OnStart: func(context.Context) error { return shutdowner.Shutdown() },
|
||||
OnStop: func(context.Context) error { return errTestStopFailed },
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
var stderr bytes.Buffer
|
||||
|
||||
exitCode := runApp(app, &stderr)
|
||||
if exitCode != 1 {
|
||||
t.Errorf("runApp() = %d, want 1", exitCode)
|
||||
}
|
||||
|
||||
want := errTestStopFailed.Error() + "\n"
|
||||
if stderr.String() != want {
|
||||
t.Errorf("stderr = %q, want %q", stderr.String(), want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRunAppReturnsShutdownExitCode checks that runApp returns the exit
|
||||
// code a shutdown request names.
|
||||
func TestRunAppReturnsShutdownExitCode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
app := fx.New(
|
||||
fx.NopLogger,
|
||||
fx.Invoke(func(lifecycle fx.Lifecycle, shutdowner fx.Shutdowner) {
|
||||
lifecycle.Append(fx.Hook{
|
||||
OnStart: func(context.Context) error {
|
||||
return shutdowner.Shutdown(fx.ExitCode(3))
|
||||
},
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
exitCode := runApp(app, io.Discard)
|
||||
if exitCode != 3 {
|
||||
t.Errorf("runApp() = %d, want 3", exitCode)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user