package main import ( "fmt" "regexp" ) type startupPhase string const ( phaseConfig startupPhase = "config" phaseSingleton startupPhase = "singleton" phasePort startupPhase = "port" phaseLogger startupPhase = "logger" phaseDatabase startupPhase = "database" phaseMigration startupPhase = "migration" phaseAdapter startupPhase = "adapter" phaseStaticResource startupPhase = "static" phaseServer startupPhase = "server" phaseTray startupPhase = "tray" ) type startupError struct { phase startupPhase message string cause error } func newStartupError(phase startupPhase, message string, cause error) *startupError { return &startupError{ phase: phase, message: redactSensitive(message), cause: cause, } } func (e *startupError) Error() string { if e == nil { return "" } if e.cause == nil { return fmt.Sprintf("%s: %s", e.phase, e.message) } return fmt.Sprintf("%s: %s: %s", e.phase, e.message, redactSensitive(e.cause.Error())) } func (e *startupError) Unwrap() error { if e == nil { return nil } return e.cause } func (e *startupError) Phase() string { if e == nil { return "" } return string(e.phase) } func (e *startupError) UserMessage() string { if e == nil { return "" } return redactSensitive(e.message) } var sensitiveReplacers = []struct { pattern *regexp.Regexp replacement string }{ {regexp.MustCompile(`(?i)(password\s*[:=]\s*)[^\s,;&]+`), `${1}`}, {regexp.MustCompile(`(?i)(api[_-]?key\s*[:=]\s*)[^\s,;&]+`), `${1}`}, {regexp.MustCompile(`(?i)(secret\s*[:=]\s*)[^\s,;&]+`), `${1}`}, {regexp.MustCompile(`([^\s:/]+):([^\s@]+)@tcp\(`), `${1}:@tcp(`}, {regexp.MustCompile(`(://[^\s:/]+):([^\s@]+)@`), `${1}:@`}, } func redactSensitive(s string) string { for _, replacer := range sensitiveReplacers { s = replacer.pattern.ReplaceAllString(s, replacer.replacement) } return s } func startupTitle() string { return appName + " 启动失败" } func startupServerErrorMessage() string { return "后端服务启动失败\n\n请检查端口占用、网络权限或查看日志获取更多信息" } func startupInternalErrorMessage() string { return "应用初始化失败\n\n请查看日志或重新安装应用" }