97 lines
2.3 KiB
Go
97 lines
2.3 KiB
Go
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}<redacted>`},
|
|
{regexp.MustCompile(`(?i)(api[_-]?key\s*[:=]\s*)[^\s,;&]+`), `${1}<redacted>`},
|
|
{regexp.MustCompile(`(?i)(secret\s*[:=]\s*)[^\s,;&]+`), `${1}<redacted>`},
|
|
{regexp.MustCompile(`([^\s:/]+):([^\s@]+)@tcp\(`), `${1}:<redacted>@tcp(`},
|
|
{regexp.MustCompile(`(://[^\s:/]+):([^\s@]+)@`), `${1}:<redacted>@`},
|
|
}
|
|
|
|
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请查看日志或重新安装应用"
|
|
}
|