fix(config): handle critical config errors

Propagate critical init and entrypoint failures to halt startup
and log them as fatal during config loading
This commit is contained in:
yusing
2026-02-05 22:56:09 +08:00
parent 211e4ad465
commit fc540ea419
3 changed files with 31 additions and 3 deletions

View File

@@ -66,6 +66,10 @@ func main() {
err := config.Load() err := config.Load()
if err != nil { if err != nil {
var criticalErr config.CriticalError
if errors.As(err, &criticalErr) {
gperr.LogFatal("critical error in config", criticalErr)
}
gperr.LogWarn("errors in config", err) gperr.LogWarn("errors in config", err)
} }

View File

@@ -60,6 +60,16 @@ func Load() error {
cfgWatcher = watcher.NewConfigFileWatcher(common.ConfigFileName) cfgWatcher = watcher.NewConfigFileWatcher(common.ConfigFileName)
initErr := state.InitFromFile(common.ConfigPath)
if initErr != nil {
// if error is critical, notify and return it without starting providers
var criticalErr CriticalError
if errors.As(initErr, &criticalErr) {
logNotifyError("init", criticalErr.err)
return criticalErr.err
}
}
// disable pool logging temporary since we already have pretty logging // disable pool logging temporary since we already have pretty logging
routes.HTTP.DisableLog(true) routes.HTTP.DisableLog(true)
routes.Stream.DisableLog(true) routes.Stream.DisableLog(true)

View File

@@ -50,6 +50,18 @@ type state struct {
tmpLog zerolog.Logger tmpLog zerolog.Logger
} }
type CriticalError struct {
err error
}
func (e CriticalError) Error() string {
return e.err.Error()
}
func (e CriticalError) Unwrap() error {
return e.err
}
func NewState() config.State { func NewState() config.State {
tmpLogBuf := bytes.NewBuffer(make([]byte, 0, 4096)) tmpLogBuf := bytes.NewBuffer(make([]byte, 0, 4096))
return &state{ return &state{
@@ -96,7 +108,7 @@ func (state *state) InitFromFile(filename string) error {
if errors.Is(err, fs.ErrNotExist) { if errors.Is(err, fs.ErrNotExist) {
state.Config = config.DefaultConfig() state.Config = config.DefaultConfig()
} else { } else {
return err return CriticalError{err}
} }
} }
return state.Init(data) return state.Init(data)
@@ -105,7 +117,7 @@ func (state *state) InitFromFile(filename string) error {
func (state *state) Init(data []byte) error { func (state *state) Init(data []byte) error {
err := serialization.UnmarshalValidate(data, &state.Config, yaml.Unmarshal) err := serialization.UnmarshalValidate(data, &state.Config, yaml.Unmarshal)
if err != nil { if err != nil {
return err return CriticalError{err}
} }
g := gperr.NewGroup("config load error") g := gperr.NewGroup("config load error")
@@ -117,7 +129,9 @@ func (state *state) Init(data []byte) error {
// these won't benefit from running on goroutines // these won't benefit from running on goroutines
errs.Add(state.initNotification()) errs.Add(state.initNotification())
errs.Add(state.initACL()) errs.Add(state.initACL())
errs.Add(state.initEntrypoint()) if err := state.initEntrypoint(); err != nil {
errs.Add(CriticalError{err})
}
errs.Add(state.loadRouteProviders()) errs.Add(state.loadRouteProviders())
return errs.Error() return errs.Error()
} }