refactor: rename module 'err' to 'gperr' in references

This commit is contained in:
yusing 2025-03-28 06:26:36 +08:00
parent e4f6994dfc
commit 361931ed96
38 changed files with 242 additions and 267 deletions

View file

@ -13,7 +13,7 @@ import (
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/config/types"
"github.com/yusing/go-proxy/internal/entrypoint"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/net/http/server"
"github.com/yusing/go-proxy/internal/notif"
@ -64,7 +64,7 @@ func newConfig() *Config {
}
}
func Load() (*Config, E.Error) {
func Load() (*Config, gperr.Error) {
if instance != nil {
return instance, nil
}
@ -83,8 +83,8 @@ func WatchChanges() {
t,
configEventFlushInterval,
OnConfigChange,
func(err E.Error) {
E.LogError("config reload error", err)
func(err gperr.Error) {
gperr.LogError("config reload error", err)
},
)
eventQueue.Start(cfgWatcher.Events(t.Context()))
@ -108,7 +108,7 @@ func OnConfigChange(ev []events.Event) {
}
}
func Reload() E.Error {
func Reload() gperr.Error {
// avoid race between config change and API reload request
reloadMu.Lock()
defer reloadMu.Unlock()
@ -117,7 +117,7 @@ func Reload() E.Error {
err := newCfg.load()
if err != nil {
newCfg.task.Finish(err)
return E.New("using last config").With(err)
return gperr.New("using last config").With(err)
}
// cancel all current subtasks -> wait
@ -132,7 +132,7 @@ func (cfg *Config) Value() *types.Config {
return instance.value
}
func (cfg *Config) Reload() E.Error {
func (cfg *Config) Reload() gperr.Error {
return Reload()
}
@ -162,20 +162,20 @@ func (cfg *Config) StartAutoCert() {
}
if err := autocert.Setup(); err != nil {
E.LogFatal("autocert setup error", err)
gperr.LogFatal("autocert setup error", err)
} else {
autocert.ScheduleRenewal(cfg.task)
}
}
func (cfg *Config) StartProxyProviders() {
errs := cfg.providers.CollectErrorsParallel(
errs := cfg.providers.CollectErrors(
func(_ string, p *proxy.Provider) error {
return p.Start(cfg.task)
})
if err := E.Join(errs...); err != nil {
E.LogError("route provider errors", err)
if err := gperr.Join(errs...); err != nil {
gperr.LogError("route provider errors", err)
}
}
@ -209,21 +209,21 @@ func (cfg *Config) StartServers(opts ...*StartServersOptions) {
}
}
func (cfg *Config) load() E.Error {
func (cfg *Config) load() gperr.Error {
const errMsg = "config load error"
data, err := os.ReadFile(common.ConfigPath)
if err != nil {
E.LogFatal(errMsg, err)
gperr.LogFatal(errMsg, err)
}
model := types.DefaultConfig()
if err := utils.DeserializeYAML(data, model); err != nil {
E.LogFatal(errMsg, err)
gperr.LogFatal(errMsg, err)
}
// errors are non fatal below
errs := E.NewBuilder(errMsg)
errs := gperr.NewBuilder(errMsg)
errs.Add(cfg.entrypoint.SetMiddlewares(model.Entrypoint.Middlewares))
errs.Add(cfg.entrypoint.SetAccessLogger(cfg.task, model.Entrypoint.AccessLog))
cfg.initNotification(model.Providers.Notification)
@ -251,7 +251,7 @@ func (cfg *Config) initNotification(notifCfg []notif.NotificationConfig) {
}
}
func (cfg *Config) initAutoCert(autocertCfg *autocert.AutocertConfig) (err E.Error) {
func (cfg *Config) initAutoCert(autocertCfg *autocert.AutocertConfig) (err gperr.Error) {
if cfg.autocertProvider != nil {
return
}
@ -260,9 +260,7 @@ func (cfg *Config) initAutoCert(autocertCfg *autocert.AutocertConfig) (err E.Err
return
}
func (cfg *Config) loadRouteProviders(providers *types.Providers) E.Error {
errs := E.NewBuilder("route provider errors")
results := E.NewBuilder("loaded route providers")
func (cfg *Config) loadRouteProviders(providers *config.Providers) gperr.Error {
lenLongestName := 0
for _, filename := range providers.Files {

View file

@ -6,7 +6,7 @@ import (
"github.com/go-playground/validator/v10"
"github.com/yusing/go-proxy/internal/autocert"
"github.com/yusing/go-proxy/internal/net/http/accesslog"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/notif"
"github.com/yusing/go-proxy/internal/utils"
@ -34,7 +34,7 @@ type (
ConfigInstance interface {
Value() *Config
Reload() E.Error
Reload() gperr.Error
Statistics() map[string]any
RouteProviderList() []string
Context() context.Context

View file

@ -1,17 +1,17 @@
package docker
import (
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
type LabelMap = map[string]any
var ErrInvalidLabel = E.New("invalid label")
var ErrInvalidLabel = gperr.New("invalid label")
func ParseLabels(labels map[string]string) (LabelMap, E.Error) {
func ParseLabels(labels map[string]string) (LabelMap, gperr.Error) {
nestedMap := make(LabelMap)
errs := E.NewBuilder("labels error")
errs := gperr.NewBuilder("labels error")
for lbl, value := range labels {
parts := strutils.SplitRune(lbl, '.')
@ -37,7 +37,7 @@ func ParseLabels(labels map[string]string) (LabelMap, E.Error) {
// Move deeper into the nested map
m, ok := currentMap[k].(LabelMap)
if !ok && currentMap[k] != "" {
errs.Add(E.Errorf("expect mapping, got %T", currentMap[k]).Subject(lbl))
errs.Add(gperr.Errorf("expect mapping, got %T", currentMap[k]).Subject(lbl))
continue
} else if !ok {
m = make(LabelMap)

View file

@ -6,7 +6,7 @@ import (
"net/url"
"strings"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
)
type ProviderBase struct {
@ -16,12 +16,12 @@ type ProviderBase struct {
}
var (
ErrMissingToken = E.New("token is required")
ErrURLMissingScheme = E.New("url missing scheme, expect 'http://' or 'https://'")
ErrMissingToken = gperr.New("token is required")
ErrURLMissingScheme = gperr.New("url missing scheme, expect 'http://' or 'https://'")
)
// Validate implements the utils.CustomValidator interface.
func (base *ProviderBase) Validate() E.Error {
func (base *ProviderBase) Validate() gperr.Error {
if base.Token == "" {
return ErrMissingToken
}
@ -30,7 +30,7 @@ func (base *ProviderBase) Validate() E.Error {
}
u, err := url.Parse(base.URL)
if err != nil {
return E.Wrap(err)
return gperr.Wrap(err)
}
base.URL = u.String()
return nil
@ -63,7 +63,7 @@ func (base *ProviderBase) SetHeaders(logMsg *LogMessage, headers http.Header) {
func (base *ProviderBase) makeRespError(resp *http.Response) error {
body, err := io.ReadAll(resp.Body)
if err == nil {
return E.Errorf("%s status %d: %s", base.Name, resp.StatusCode, body)
return gperr.Errorf("%s status %d: %s", base.Name, resp.StatusCode, body)
}
return E.Errorf("%s status %d", base.Name, resp.StatusCode)
return gperr.Errorf("%s status %d", base.Name, resp.StatusCode)
}

View file

@ -1,7 +1,7 @@
package notif
import (
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils"
)
@ -11,13 +11,13 @@ type NotificationConfig struct {
}
var (
ErrMissingNotifProvider = E.New("missing notification provider")
ErrInvalidNotifProviderType = E.New("invalid notification provider type")
ErrUnknownNotifProvider = E.New("unknown notification provider")
ErrMissingNotifProvider = gperr.New("missing notification provider")
ErrInvalidNotifProviderType = gperr.New("invalid notification provider type")
ErrUnknownNotifProvider = gperr.New("unknown notification provider")
)
// UnmarshalMap implements MapUnmarshaler.
func (cfg *NotificationConfig) UnmarshalMap(m map[string]any) (err E.Error) {
func (cfg *NotificationConfig) UnmarshalMap(m map[string]any) (err gperr.Error) {
// extract provider name
providerName := m["provider"]
switch providerName := providerName.(type) {

View file

@ -2,7 +2,7 @@ package notif
import (
"github.com/rs/zerolog"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/task"
F "github.com/yusing/go-proxy/internal/utils/functional"
@ -89,29 +89,15 @@ func (disp *Dispatcher) dispatch(msg *LogMessage) {
task := disp.task.Subtask("dispatcher")
defer task.Finish("notif dispatched")
errs := E.NewBuilder(dispatchErr)
errs := gperr.NewBuilder(dispatchErr)
disp.providers.RangeAllParallel(func(p Provider) {
if err := notifyProvider(task.Context(), p, msg); err != nil {
errs.Add(E.PrependSubject(p.GetName(), err))
errs.Add(gperr.PrependSubject(p.GetName(), err))
}
})
if errs.HasError() {
E.LogError(errs.About(), errs.Error())
gperr.LogError(errs.About(), errs.Error())
} else {
logging.Debug().Str("title", msg.Title).Msgf("dispatched notif")
}
}
// Run implements zerolog.Hook.
// func (disp *Dispatcher) Run(e *zerolog.Event, level zerolog.Level, message string) {
// if strings.HasPrefix(message, dispatchErr) { // prevent recursion
// return
// }
// switch level {
// case zerolog.WarnLevel, zerolog.ErrorLevel, zerolog.FatalLevel, zerolog.PanicLevel:
// disp.logCh <- &LogMessage{
// Level: level,
// Message: message,
// }
// }
// }

View file

@ -7,7 +7,7 @@ import (
"strings"
"github.com/rs/zerolog"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
)
// See https://docs.ntfy.sh/publish
@ -24,22 +24,22 @@ const (
NtfyStylePlain NtfyStyle = "plain"
)
func (n *Ntfy) Validate() E.Error {
func (n *Ntfy) Validate() gperr.Error {
if n.URL == "" {
return E.New("url is required")
return gperr.New("url is required")
}
if n.Topic == "" {
return E.New("topic is required")
return gperr.New("topic is required")
}
if n.Topic[0] == '/' {
return E.New("topic should not start with a slash")
return gperr.New("topic should not start with a slash")
}
switch n.Style {
case "":
n.Style = NtfyStyleMarkdown
case NtfyStyleMarkdown, NtfyStylePlain:
default:
return E.Errorf("invalid style, expecting %q or %q, got %q", NtfyStyleMarkdown, NtfyStylePlain, n.Style)
return gperr.Errorf("invalid style, expecting %q or %q, got %q", NtfyStyleMarkdown, NtfyStylePlain, n.Style)
}
return nil
}

View file

@ -6,8 +6,8 @@ import (
"net/http"
"time"
E "github.com/yusing/go-proxy/internal/error"
gphttp "github.com/yusing/go-proxy/internal/net/http"
"github.com/yusing/go-proxy/internal/gperr"
gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/utils"
)
@ -26,7 +26,7 @@ type (
makeRespError(resp *http.Response) error
}
ProviderCreateFunc func(map[string]any) (Provider, E.Error)
ProviderCreateFunc func(map[string]any) (Provider, gperr.Error)
ProviderConfig map[string]any
)
@ -39,7 +39,7 @@ const (
func notifyProvider(ctx context.Context, provider Provider, msg *LogMessage) error {
body, err := provider.MakeBody(msg)
if err != nil {
return E.PrependSubject(provider.GetName(), err)
return gperr.PrependSubject(provider.GetName(), err)
}
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
@ -52,7 +52,7 @@ func notifyProvider(ctx context.Context, provider Provider, msg *LogMessage) err
body,
)
if err != nil {
return E.PrependSubject(provider.GetName(), err)
return gperr.PrependSubject(provider.GetName(), err)
}
req.Header.Set("Content-Type", provider.GetMIMEType())
@ -63,7 +63,7 @@ func notifyProvider(ctx context.Context, provider Provider, msg *LogMessage) err
resp, err := http.DefaultClient.Do(req)
if err != nil {
return E.PrependSubject(provider.GetName(), err)
return gperr.PrependSubject(provider.GetName(), err)
}
defer resp.Body.Close()

View file

@ -8,7 +8,7 @@ import (
"net/http"
"strings"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
)
type Webhook struct {
@ -27,7 +27,7 @@ var webhookTemplates = map[string]string{
"discord": discordPayload,
}
func (webhook *Webhook) Validate() E.Error {
func (webhook *Webhook) Validate() gperr.Error {
if err := webhook.ProviderBase.Validate(); err != nil && !err.Is(ErrMissingToken) {
return err
}
@ -37,16 +37,16 @@ func (webhook *Webhook) Validate() E.Error {
webhook.MIMEType = "application/json"
case "application/json", "application/x-www-form-urlencoded", "text/plain":
default:
return E.New("invalid mime_type, expect empty, 'application/json', 'application/x-www-form-urlencoded' or 'text/plain'")
return gperr.New("invalid mime_type, expect empty, 'application/json', 'application/x-www-form-urlencoded' or 'text/plain'")
}
switch webhook.Template {
case "":
if webhook.MIMEType == "application/json" && !json.Valid([]byte(webhook.Payload)) {
return E.New("invalid payload, expect valid JSON")
return gperr.New("invalid payload, expect valid JSON")
}
if webhook.Payload == "" {
return E.New("invalid payload, expect non-empty")
return gperr.New("invalid payload, expect non-empty")
}
case "discord":
webhook.ColorMode = "dec"
@ -56,7 +56,7 @@ func (webhook *Webhook) Validate() E.Error {
webhook.Payload = discordPayload
}
default:
return E.New("invalid template, expect empty or 'discord'")
return gperr.New("invalid template, expect empty or 'discord'")
}
switch webhook.Method {
@ -64,7 +64,7 @@ func (webhook *Webhook) Validate() E.Error {
webhook.Method = http.MethodPost
case http.MethodGet, http.MethodPost, http.MethodPut:
default:
return E.New("invalid method, expect empty, 'GET', 'POST' or 'PUT'")
return gperr.New("invalid method, expect empty, 'GET', 'POST' or 'PUT'")
}
switch webhook.ColorMode {
@ -72,7 +72,7 @@ func (webhook *Webhook) Validate() E.Error {
webhook.ColorMode = "hex"
case "hex", "dec":
default:
return E.New("invalid color_mode, expect empty, 'hex' or 'dec'")
return gperr.New("invalid color_mode, expect empty, 'hex' or 'dec'")
}
return nil

View file

@ -6,10 +6,7 @@ import (
"path/filepath"
"github.com/yusing/go-proxy/internal/common"
gphttp "github.com/yusing/go-proxy/internal/net/http"
"github.com/yusing/go-proxy/internal/net/http/accesslog"
"github.com/yusing/go-proxy/internal/net/http/middleware"
metricslogger "github.com/yusing/go-proxy/internal/net/http/middleware/metrics_logger"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/route/routes"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/watcher/health"
@ -35,12 +32,12 @@ func handler(root string) http.Handler {
return http.FileServer(http.Dir(root))
}
func NewFileServer(base *Route) (*FileServer, E.Error) {
func NewFileServer(base *Route) (*FileServer, gperr.Error) {
s := &FileServer{Route: base}
s.Root = filepath.Clean(s.Root)
if !path.IsAbs(s.Root) {
return nil, E.New("`root` must be an absolute path")
return nil, gperr.New("`root` must be an absolute path")
}
s.handler = handler(s.Root)
@ -57,7 +54,7 @@ func NewFileServer(base *Route) (*FileServer, E.Error) {
}
// Start implements task.TaskStarter.
func (s *FileServer) Start(parent task.Parent) E.Error {
func (s *FileServer) Start(parent task.Parent) gperr.Error {
s.task = parent.Subtask("fileserver."+s.TargetName(), false)
pathPatterns := s.PathPatterns
@ -66,7 +63,7 @@ func (s *FileServer) Start(parent task.Parent) E.Error {
case len(pathPatterns) == 1 && pathPatterns[0] == "/":
default:
mux := gphttp.NewServeMux()
patErrs := E.NewBuilder("invalid path pattern(s)")
patErrs := gperr.NewBuilder("invalid path pattern(s)")
for _, p := range pathPatterns {
patErrs.Add(mux.Handle(p, s.handler))
}
@ -88,7 +85,7 @@ func (s *FileServer) Start(parent task.Parent) E.Error {
s.accessLogger, err = accesslog.NewFileAccessLogger(s.task, s.AccessLog)
if err != nil {
s.task.Finish(err)
return E.Wrap(err)
return gperr.Wrap(err)
}
}

View file

@ -8,7 +8,7 @@ import (
"github.com/rs/zerolog"
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/docker"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/route"
U "github.com/yusing/go-proxy/internal/utils"
@ -27,7 +27,7 @@ const (
aliasRefPrefixAlt = '$'
)
var ErrAliasRefIndexOutOfRange = E.New("index out of range")
var ErrAliasRefIndexOutOfRange = gperr.New("index out of range")
func DockerProviderImpl(name, dockerHost string) (ProviderImpl, error) {
if dockerHost == common.DockerHostFromEnv {
@ -60,13 +60,12 @@ func (p *DockerProvider) NewWatcher() watcher.Watcher {
return watcher.NewDockerWatcher(p.dockerHost)
}
func (p *DockerProvider) loadRoutesImpl() (route.Routes, E.Error) {
containers, err := docker.ListContainers(p.dockerHost)
func (p *DockerProvider) loadRoutesImpl() (route.Routes, gperr.Error) {
if err != nil {
return nil, E.From(err)
return nil, gperr.Wrap(err)
}
errs := E.NewBuilder("")
errs := gperr.NewBuilder("")
routes := make(route.Routes)
for _, c := range containers {
@ -93,7 +92,7 @@ func (p *DockerProvider) loadRoutesImpl() (route.Routes, E.Error) {
// Returns a list of proxy entries for a container.
// Always non-nil.
func (p *DockerProvider) routesFromContainerLabels(container *docker.Container) (route.Routes, E.Error) {
func (p *DockerProvider) routesFromContainerLabels(container *docker.Container) (route.Routes, gperr.Error) {
if !container.IsExplicit && p.IsExplicitOnly() {
return nil, nil
}
@ -109,7 +108,7 @@ func (p *DockerProvider) routesFromContainerLabels(container *docker.Container)
}
}
errs := E.NewBuilder("label errors")
errs := gperr.NewBuilder("label errors")
m, err := docker.ParseLabels(container.Labels)
errs.Add(err)
@ -118,7 +117,7 @@ func (p *DockerProvider) routesFromContainerLabels(container *docker.Container)
for alias, entryMapAny := range m {
if len(alias) == 0 {
errs.Add(E.New("empty alias"))
errs.Add(gperr.New("empty alias"))
continue
}
@ -132,7 +131,7 @@ func (p *DockerProvider) routesFromContainerLabels(container *docker.Container)
panic(fmt.Errorf("invalid entry map type %T", entryMapAny))
}
if err := yaml.Unmarshal([]byte(yamlStr), &entryMap); err != nil {
errs.Add(E.From(err).Subject(alias))
errs.Add(gperr.Wrap(err).Subject(alias))
continue
}
}

View file

@ -1,8 +1,7 @@
package provider
import (
"github.com/yusing/go-proxy/internal/common"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/route"
"github.com/yusing/go-proxy/internal/route/provider/types"
"github.com/yusing/go-proxy/internal/task"
@ -12,19 +11,19 @@ import (
type EventHandler struct {
provider *Provider
errs *E.Builder
added *E.Builder
removed *E.Builder
updated *E.Builder
errs *gperr.Builder
added *gperr.Builder
removed *gperr.Builder
updated *gperr.Builder
}
func (p *Provider) newEventHandler() *EventHandler {
return &EventHandler{
provider: p,
errs: E.NewBuilder("event errors"),
added: E.NewBuilder("added"),
removed: E.NewBuilder("removed"),
updated: E.NewBuilder("updated"),
errs: gperr.NewBuilder("event errors"),
added: gperr.NewBuilder("added"),
removed: gperr.NewBuilder("removed"),
updated: gperr.NewBuilder("updated"),
}
}
@ -121,7 +120,7 @@ func (handler *EventHandler) Update(parent task.Parent, oldRoute *route.Route, n
}
func (handler *EventHandler) Log() {
results := E.NewBuilder("event occurred")
results := gperr.NewBuilder("event occurred")
results.AddFrom(handler.added, false)
results.AddFrom(handler.removed, false)
results.AddFrom(handler.updated, false)

View file

@ -7,7 +7,7 @@ import (
"github.com/rs/zerolog"
"github.com/yusing/go-proxy/internal/common"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/route"
"github.com/yusing/go-proxy/internal/utils"
@ -33,12 +33,12 @@ func FileProviderImpl(filename string) (ProviderImpl, error) {
return impl, nil
}
func validate(data []byte) (routes route.Routes, err E.Error) {
func validate(data []byte) (routes route.Routes, err gperr.Error) {
err = utils.DeserializeYAML(data, &routes)
return
}
func Validate(data []byte) (err E.Error) {
func Validate(data []byte) (err gperr.Error) {
_, err = validate(data)
return
}
@ -59,16 +59,16 @@ func (p *FileProvider) Logger() *zerolog.Logger {
return &p.l
}
func (p *FileProvider) loadRoutesImpl() (route.Routes, E.Error) {
func (p *FileProvider) loadRoutesImpl() (route.Routes, gperr.Error) {
data, err := os.ReadFile(p.path)
if err != nil {
return nil, E.Wrap(err)
return nil, gperr.Wrap(err)
}
routes, err := validate(data)
if err != nil && len(routes) == 0 {
return nil, E.Wrap(err)
return nil, gperr.Wrap(err)
}
return routes, E.Wrap(err)
return routes, gperr.Wrap(err)
}
func (p *FileProvider) NewWatcher() W.Watcher {

View file

@ -7,7 +7,7 @@ import (
"time"
"github.com/rs/zerolog"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/route"
"github.com/yusing/go-proxy/internal/route/provider/types"
"github.com/yusing/go-proxy/internal/task"
@ -28,7 +28,7 @@ type (
fmt.Stringer
ShortName() string
IsExplicitOnly() bool
loadRoutesImpl() (route.Routes, E.Error)
loadRoutesImpl() (route.Routes, gperr.Error)
NewWatcher() W.Watcher
Logger() *zerolog.Logger
}
@ -92,10 +92,10 @@ func (p *Provider) startRoute(parent task.Parent, r *route.Route) E.Error {
}
// Start implements task.TaskStarter.
func (p *Provider) Start(parent task.Parent) E.Error {
func (p *Provider) Start(parent task.Parent) gperr.Error {
t := parent.Subtask("provider."+p.String(), false)
errs := E.NewBuilder("routes error")
errs := gperr.NewBuilder("routes error")
for _, r := range p.routes {
errs.Add(p.startRoute(t, r))
}
@ -109,8 +109,8 @@ func (p *Provider) Start(parent task.Parent) E.Error {
handler.Handle(t, events)
handler.Log()
},
func(err E.Error) {
E.LogError("event error", err, p.Logger())
func(err gperr.Error) {
gperr.LogError("event error", err, p.Logger())
},
)
eventQueue.Start(p.watcher.Events(t.Context()))
@ -132,12 +132,12 @@ func (p *Provider) GetRoute(alias string) (r *route.Route, ok bool) {
return
}
func (p *Provider) loadRoutes() (routes route.Routes, err E.Error) {
func (p *Provider) loadRoutes() (routes route.Routes, err gperr.Error) {
routes, err = p.loadRoutesImpl()
if err != nil && len(routes) == 0 {
return route.Routes{}, err
}
errs := E.NewBuilder("routes error")
errs := gperr.NewBuilder("routes error")
errs.Add(err)
// check for exclusion
// set alias and provider, then validate
@ -156,7 +156,7 @@ func (p *Provider) loadRoutes() (routes route.Routes, err E.Error) {
return routes, errs.Error()
}
func (p *Provider) LoadRoutes() (err E.Error) {
func (p *Provider) LoadRoutes() (err gperr.Error) {
p.routes, err = p.loadRoutes()
return
}

View file

@ -7,7 +7,7 @@ import (
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/docker"
"github.com/yusing/go-proxy/internal/docker/idlewatcher"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
gphttp "github.com/yusing/go-proxy/internal/net/http"
"github.com/yusing/go-proxy/internal/net/http/accesslog"
@ -38,8 +38,7 @@ type (
// var globalMux = http.NewServeMux() // TODO: support regex subdomain matching.
func NewReverseProxyRoute(base *Route) (*ReveseProxyRoute, E.Error) {
trans := gphttp.DefaultTransport
func NewReverseProxyRoute(base *Route) (*ReveseProxyRoute, gperr.Error) {
httpConfig := base.HTTPConfig
if httpConfig.NoTLSVerify {
@ -72,7 +71,7 @@ func (r *ReveseProxyRoute) String() string {
}
// Start implements task.TaskStarter.
func (r *ReveseProxyRoute) Start(parent task.Parent) E.Error {
func (r *ReveseProxyRoute) Start(parent task.Parent) gperr.Error {
r.task = parent.Subtask("http."+r.TargetName(), false)
switch {
@ -103,7 +102,7 @@ func (r *ReveseProxyRoute) Start(parent task.Parent) E.Error {
r.rp.AccessLogger, err = accesslog.NewFileAccessLogger(r.task, r.AccessLog)
if err != nil {
r.task.Finish(err)
return E.From(err)
return gperr.Wrap(err)
}
}
@ -119,7 +118,7 @@ func (r *ReveseProxyRoute) Start(parent task.Parent) E.Error {
Str("route", r.TargetName()).
Msg("`path_patterns` for reverse proxy is deprecated. Use `rules` instead.")
mux := gphttp.NewServeMux()
patErrs := E.NewBuilder("invalid path pattern(s)")
patErrs := gperr.NewBuilder("invalid path pattern(s)")
for _, p := range pathPatterns {
patErrs.Add(mux.HandleFunc(p, r.rp.HandlerFunc))
}

View file

@ -7,12 +7,12 @@ import (
"github.com/yusing/go-proxy/internal/docker"
idlewatcher "github.com/yusing/go-proxy/internal/docker/idlewatcher/types"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/homepage"
net "github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/watcher/health"
dockertypes "github.com/docker/docker/api/types"
"github.com/yusing/go-proxy/internal/common"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/net/http/accesslog"
@ -65,14 +65,14 @@ func (r Routes) Contains(alias string) bool {
return ok
}
func (r *Route) Validate() (err E.Error) {
func (r *Route) Validate() (err gperr.Error) {
if r.isValidated {
return nil
}
r.isValidated = true
r.Finalize()
errs := E.NewBuilder("entry validation failed")
errs := gperr.NewBuilder("entry validation failed")
switch r.Scheme {
case types.SchemeFileServer:
@ -86,18 +86,18 @@ func (r *Route) Validate() (err E.Error) {
}
fallthrough
case types.SchemeTCP, types.SchemeUDP:
r.LisURL = E.Collect(errs, net.ParseURL, fmt.Sprintf("%s://%s:%d", r.Scheme, r.Host, r.Port.Listening))
r.LisURL = gperr.Collect(errs, net.ParseURL, fmt.Sprintf("%s://:%d", r.Scheme, r.Port.Listening))
fallthrough
default:
if r.LoadBalance != nil && r.LoadBalance.Link == "" {
r.LoadBalance = nil
}
r.ProxyURL = E.Collect(errs, net.ParseURL, fmt.Sprintf("%s://%s:%d", r.Scheme, r.Host, r.Port.Proxy))
r.Idlewatcher = E.Collect(errs, idlewatcher.ValidateConfig, r.Container)
r.ProxyURL = gperr.Collect(errs, net.ParseURL, fmt.Sprintf("%s://%s:%d", r.Scheme, r.Host, r.Port.Proxy))
r.Idlewatcher = gperr.Collect(errs, idlewatcher.ValidateConfig, r.Container)
}
if !r.UseHealthCheck() && (r.UseLoadBalance() || r.UseIdleWatcher()) {
errs.Adds("healthCheck.disable cannot be true when loadbalancer or idlewatcher is enabled")
errs.Adds("cannot disable healthcheck when loadbalancer or idle watcher is enabled")
}
if errs.HasError() {
@ -118,10 +118,11 @@ func (r *Route) Validate() (err E.Error) {
return err
}
func (r *Route) Start(parent task.Parent) (err E.Error) {
func (r *Route) Start(parent task.Parent) (err gperr.Error) {
if r.impl == nil {
return E.New("route not initialized")
return gperr.New("route not initialized")
}
return r.impl.Start(parent)
}

View file

@ -41,9 +41,7 @@ func NewCache() Cache {
// Release clear the contents of the Cached and returns it to the pool.
func (c Cache) Release() {
for _, k := range cacheKeys {
delete(c, k)
}
clear(c)
cachePool.Put(c)
}

View file

@ -6,9 +6,9 @@ import (
"strconv"
"strings"
E "github.com/yusing/go-proxy/internal/error"
gphttp "github.com/yusing/go-proxy/internal/net/http"
"github.com/yusing/go-proxy/internal/net/http/reverseproxy"
"github.com/yusing/go-proxy/internal/gperr"
gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/net/gphttp/reverseproxy"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@ -47,7 +47,7 @@ var commands = map[string]struct {
"to": "the path to rewrite to, must start with /",
},
},
validate: func(args []string) (any, E.Error) {
validate: func(args []string) (any, gperr.Error) {
if len(args) != 2 {
return nil, ErrExpectTwoArgs
}
@ -109,7 +109,7 @@ var commands = map[string]struct {
"text": "the error message to return",
},
},
validate: func(args []string) (any, E.Error) {
validate: func(args []string) (any, gperr.Error) {
if len(args) != 2 {
return nil, ErrExpectTwoArgs
}
@ -137,7 +137,7 @@ var commands = map[string]struct {
"realm": "the authentication realm",
},
},
validate: func(args []string) (any, E.Error) {
validate: func(args []string) (any, gperr.Error) {
if len(args) == 1 {
return args[0], nil
}
@ -164,7 +164,7 @@ var commands = map[string]struct {
if target.Scheme == "" {
target.Scheme = "http"
}
rp := reverseproxy.NewReverseProxy("", target, gphttp.DefaultTransport)
rp := reverseproxy.NewReverseProxy("", target, gphttp.NewTransport())
return ReturningCommand(rp.ServeHTTP)
},
},
@ -176,7 +176,7 @@ var commands = map[string]struct {
"value": "the value to set",
},
},
validate: func(args []string) (any, E.Error) {
validate: func(args []string) (any, gperr.Error) {
return validateModField(ModFieldSet, args)
},
build: func(args any) CommandHandler {
@ -191,7 +191,7 @@ var commands = map[string]struct {
"value": "the value to add",
},
},
validate: func(args []string) (any, E.Error) {
validate: func(args []string) (any, gperr.Error) {
return validateModField(ModFieldAdd, args)
},
build: func(args any) CommandHandler {
@ -205,7 +205,7 @@ var commands = map[string]struct {
"field": "the field to remove",
},
},
validate: func(args []string) (any, E.Error) {
validate: func(args []string) (any, gperr.Error) {
return validateModField(ModFieldRemove, args)
},
build: func(args any) CommandHandler {

View file

@ -1,18 +1,20 @@
package rules
import E "github.com/yusing/go-proxy/internal/error"
import (
"github.com/yusing/go-proxy/internal/gperr"
)
var (
ErrUnterminatedQuotes = E.New("unterminated quotes")
ErrUnsupportedEscapeChar = E.New("unsupported escape char")
ErrUnknownDirective = E.New("unknown directive")
ErrInvalidArguments = E.New("invalid arguments")
ErrInvalidOnTarget = E.New("invalid `rule.on` target")
ErrInvalidCommandSequence = E.New("invalid command sequence")
ErrInvalidSetTarget = E.New("invalid `rule.set` target")
ErrUnterminatedQuotes = gperr.New("unterminated quotes")
ErrUnsupportedEscapeChar = gperr.New("unsupported escape char")
ErrUnknownDirective = gperr.New("unknown directive")
ErrInvalidArguments = gperr.New("invalid arguments")
ErrInvalidOnTarget = gperr.New("invalid `rule.on` target")
ErrInvalidCommandSequence = gperr.New("invalid command sequence")
ErrInvalidSetTarget = gperr.New("invalid `rule.set` target")
ErrExpectNoArg = E.Wrap(ErrInvalidArguments, "expect no arg")
ErrExpectOneArg = E.Wrap(ErrInvalidArguments, "expect 1 arg")
ErrExpectTwoArgs = E.Wrap(ErrInvalidArguments, "expect 2 args")
ErrExpectKVOptionalV = E.Wrap(ErrInvalidArguments, "expect 'key' or 'key value'")
ErrExpectNoArg = gperr.Wrap(ErrInvalidArguments, "expect no arg")
ErrExpectOneArg = gperr.Wrap(ErrInvalidArguments, "expect 1 arg")
ErrExpectTwoArgs = gperr.Wrap(ErrInvalidArguments, "expect 2 args")
ErrExpectKVOptionalV = gperr.Wrap(ErrInvalidArguments, "expect 'key' or 'key value'")
)

View file

@ -3,7 +3,7 @@ package rules
import (
"net/http"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@ -240,7 +240,7 @@ func (on *RuleOn) Parse(v string) error {
lines := strutils.SplitLine(v)
checkAnd := make(CheckMatchAll, 0, len(lines))
errs := E.NewBuilder("rule.on syntax errors")
errs := gperr.NewBuilder("rule.on syntax errors")
for i, line := range lines {
if line == "" {
continue
@ -265,11 +265,11 @@ func (on *RuleOn) MarshalText() ([]byte, error) {
return []byte(on.String()), nil
}
func parseOn(line string) (Checker, E.Error) {
func parseOn(line string) (Checker, gperr.Error) {
ors := strutils.SplitRune(line, '|')
if len(ors) > 1 {
errs := E.NewBuilder("rule.on syntax errors")
errs := gperr.NewBuilder("rule.on syntax errors")
checkOr := make(CheckMatchSingle, len(ors))
for i, or := range ors {
curCheckers, err := parseOn(or)

View file

@ -7,7 +7,7 @@ import (
"net/url"
"testing"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
. "github.com/yusing/go-proxy/internal/utils/testing"
"golang.org/x/crypto/bcrypt"
)
@ -16,7 +16,7 @@ func TestParseOn(t *testing.T) {
tests := []struct {
name string
input string
wantErr E.Error
wantErr gperr.Error
}{
// header
{

View file

@ -4,7 +4,7 @@ import (
"bytes"
"unicode"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
)
var escapedChars = map[rune]rune{
@ -23,7 +23,7 @@ var escapedChars = map[rune]rune{
//
// error 403 "Forbidden 'foo' 'bar'"
// error 403 Forbidden\ \"foo\"\ \"bar\".
func parse(v string) (subject string, args []string, err E.Error) {
func parse(v string) (subject string, args []string, err gperr.Error) {
buf := bytes.NewBuffer(make([]byte, 0, len(v)))
escaped := false

View file

@ -4,7 +4,7 @@ import (
"strconv"
"testing"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
@ -14,7 +14,7 @@ func TestParser(t *testing.T) {
input string
subject string
args []string
wantErr E.Error
wantErr gperr.Error
}{
{
name: "basic",

View file

@ -6,13 +6,13 @@ import (
"path"
"strings"
E "github.com/yusing/go-proxy/internal/error"
gphttp "github.com/yusing/go-proxy/internal/net/http"
"github.com/yusing/go-proxy/internal/gperr"
gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/net/types"
)
type (
ValidateFunc func(args []string) (any, E.Error)
ValidateFunc func(args []string) (any, gperr.Error)
Tuple[T1, T2 any] struct {
First T1
Second T2
@ -29,7 +29,7 @@ func (t *Tuple[T1, T2]) String() string {
}
// toStrTuple returns *StrTuple.
func toStrTuple(args []string) (any, E.Error) {
func toStrTuple(args []string) (any, gperr.Error) {
if len(args) != 2 {
return nil, ErrExpectTwoArgs
}
@ -37,7 +37,7 @@ func toStrTuple(args []string) (any, E.Error) {
}
// toKVOptionalV returns *StrTuple that value is optional.
func toKVOptionalV(args []string) (any, E.Error) {
func toKVOptionalV(args []string) (any, gperr.Error) {
switch len(args) {
case 1:
return &StrTuple{args[0], ""}, nil
@ -49,7 +49,7 @@ func toKVOptionalV(args []string) (any, E.Error) {
}
// validateURL returns types.URL with the URL validated.
func validateURL(args []string) (any, E.Error) {
func validateURL(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@ -61,7 +61,7 @@ func validateURL(args []string) (any, E.Error) {
}
// validateAbsoluteURL returns types.URL with the URL validated.
func validateAbsoluteURL(args []string) (any, E.Error) {
func validateAbsoluteURL(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@ -79,7 +79,7 @@ func validateAbsoluteURL(args []string) (any, E.Error) {
}
// validateCIDR returns types.CIDR with the CIDR validated.
func validateCIDR(args []string) (any, E.Error) {
func validateCIDR(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@ -94,7 +94,7 @@ func validateCIDR(args []string) (any, E.Error) {
}
// validateURLPath returns string with the path validated.
func validateURLPath(args []string) (any, E.Error) {
func validateURLPath(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@ -112,8 +112,8 @@ func validateURLPath(args []string) (any, E.Error) {
}
// validateURLPaths returns []string with each element validated.
func validateURLPaths(paths []string) (any, E.Error) {
errs := E.NewBuilder("invalid url paths")
func validateURLPaths(paths []string) (any, gperr.Error) {
errs := gperr.NewBuilder("invalid url paths")
for i, p := range paths {
val, err := validateURLPath([]string{p})
if err != nil {
@ -129,7 +129,7 @@ func validateURLPaths(paths []string) (any, E.Error) {
}
// validateFSPath returns string with the path validated.
func validateFSPath(args []string) (any, E.Error) {
func validateFSPath(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@ -141,7 +141,7 @@ func validateFSPath(args []string) (any, E.Error) {
}
// validateMethod returns string with the method validated.
func validateMethod(args []string) (any, E.Error) {
func validateMethod(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@ -153,7 +153,7 @@ func validateMethod(args []string) (any, E.Error) {
}
// validateUserBCryptPassword returns *HashedCrendential with the password validated.
func validateUserBCryptPassword(args []string) (any, E.Error) {
func validateUserBCryptPassword(args []string) (any, gperr.Error) {
if len(args) != 2 {
return nil, ErrExpectTwoArgs
}
@ -161,7 +161,7 @@ func validateUserBCryptPassword(args []string) (any, E.Error) {
}
// validateModField returns CommandHandler with the field validated.
func validateModField(mod FieldModifier, args []string) (CommandHandler, E.Error) {
func validateModField(mod FieldModifier, args []string) (CommandHandler, gperr.Error) {
setField, ok := modFields[args[0]]
if !ok {
return nil, ErrInvalidSetTarget.Subject(args[0])

View file

@ -30,7 +30,7 @@ type StreamRoute struct {
l zerolog.Logger
}
func NewStreamRoute(base *Route) (route.Route, E.Error) {
func NewStreamRoute(base *Route) (route.Route, gperr.Error) {
// TODO: support non-coherent scheme
return &StreamRoute{
Route: base,
@ -46,7 +46,7 @@ func (r *StreamRoute) String() string {
}
// Start implements task.TaskStarter.
func (r *StreamRoute) Start(parent task.Parent) E.Error {
func (r *StreamRoute) Start(parent task.Parent) gperr.Error {
r.task = parent.Subtask("stream." + r.TargetName())
r.Stream = NewStream(r)
parent.OnCancel("finish", func() {
@ -78,14 +78,14 @@ func (r *StreamRoute) Start(parent task.Parent) E.Error {
if err := r.Stream.Setup(); err != nil {
r.task.Finish(err)
return E.From(err)
return gperr.Wrap(err)
}
r.l.Info().Int("port", r.Port.Listening).Msg("listening")
if r.HealthMon != nil {
if err := r.HealthMon.Start(r.task); err != nil {
E.LogWarn("health monitor error", err, &r.l)
gperr.LogWarn("health monitor error", err, &r.l)
}
}
@ -125,7 +125,7 @@ func (r *StreamRoute) acceptConnections() {
select {
case <-r.task.Context().Done():
default:
E.LogError("accept connection error", err, &r.l)
gperr.LogError("accept connection error", err, &r.l)
}
r.task.Finish(err)
return
@ -136,7 +136,7 @@ func (r *StreamRoute) acceptConnections() {
go func() {
err := r.Stream.Handle(conn)
if err != nil && !errors.Is(err, context.Canceled) {
E.LogError("handle connection error", err, &r.l)
gperr.LogError("handle connection error", err, &r.l)
}
}()
}

View file

@ -3,7 +3,7 @@ package types
import (
"strconv"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@ -13,8 +13,8 @@ type Port struct {
}
var (
ErrInvalidPortSyntax = E.New("invalid port syntax, expect [listening_port:]target_port")
ErrPortOutOfRange = E.New("port out of range")
ErrInvalidPortSyntax = gperr.New("invalid port syntax, expect [listening_port:]target_port")
ErrPortOutOfRange = gperr.New("port out of range")
)
// Parse implements strutils.Parser.
@ -28,7 +28,7 @@ func (p *Port) Parse(v string) (err error) {
var err2 error
p.Listening, err = strconv.Atoi(parts[0])
p.Proxy, err2 = strconv.Atoi(parts[1])
err = E.Join(err, err2)
err = gperr.Join(err, err2)
default:
return ErrInvalidPortSyntax.Subject(v)
}

View file

@ -1,12 +1,12 @@
package types
import (
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
)
type Scheme string
var ErrInvalidScheme = E.New("invalid scheme")
var ErrInvalidScheme = gperr.New("invalid scheme")
const (
SchemeHTTP Scheme = "http"
@ -16,7 +16,7 @@ const (
SchemeFileServer Scheme = "fileserver"
)
func (s Scheme) Validate() E.Error {
func (s Scheme) Validate() gperr.Error {
switch s {
case SchemeHTTP, SchemeHTTPS,
SchemeTCP, SchemeUDP, SchemeFileServer:

View file

@ -6,7 +6,7 @@ import (
"net"
"sync"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/net/types"
F "github.com/yusing/go-proxy/internal/utils/functional"
@ -192,7 +192,7 @@ func (w *UDPForwarder) Handle(streamConn types.StreamConn) error {
}
func (w *UDPForwarder) Close() error {
errs := E.NewBuilder("errors closing udp conn")
errs := gperr.NewBuilder("errors closing udp conn")
w.mu.Lock()
defer w.mu.Unlock()
w.connMap.RangeAll(func(key string, conn *UDPConn) {

View file

@ -8,7 +8,7 @@ import (
"time"
"github.com/yusing/go-proxy/internal/common"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@ -19,7 +19,7 @@ type (
// and returns an error if it fails to start.
//
// callerSubtask.Finish must be called when start fails or the object is finished.
Start(parent Parent) E.Error
Start(parent Parent) gperr.Error
Task() *Task
}
TaskFinisher interface {

View file

@ -7,7 +7,7 @@ import (
"sync"
"syscall"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
)
// TODO: move to "utils/io".
@ -81,10 +81,10 @@ func NewBidirectionalPipe(ctx context.Context, rw1 io.ReadWriteCloser, rw2 io.Re
}
}
func (p BidirectionalPipe) Start() E.Error {
func (p BidirectionalPipe) Start() gperr.Error {
var wg sync.WaitGroup
wg.Add(2)
b := E.NewBuilder("bidirectional pipe error")
b := gperr.NewBuilder("bidirectional pipe error")
go func() {
b.Add(p.pSrcDst.Start())
wg.Done()

View file

@ -11,7 +11,7 @@ import (
"time"
"github.com/go-playground/validator/v10"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils/functional"
"github.com/yusing/go-proxy/internal/utils/strutils"
"gopkg.in/yaml.v3"
@ -20,15 +20,15 @@ import (
type SerializedObject = map[string]any
type MapUnmarshaller interface {
UnmarshalMap(m map[string]any) E.Error
UnmarshalMap(m map[string]any) gperr.Error
}
var (
ErrInvalidType = E.New("invalid type")
ErrNilValue = E.New("nil")
ErrUnsettable = E.New("unsettable")
ErrUnsupportedConversion = E.New("unsupported conversion")
ErrUnknownField = E.New("unknown field")
ErrInvalidType = gperr.New("invalid type")
ErrNilValue = gperr.New("nil")
ErrUnsettable = gperr.New("unsettable")
ErrUnsupportedConversion = gperr.New("unsupported conversion")
ErrUnknownField = gperr.New("unknown field")
)
var (
@ -89,8 +89,8 @@ func extractFields(t reflect.Type) (all, anonymous []reflect.StructField) {
return fields, anonymous
}
func ValidateWithFieldTags(s any) E.Error {
errs := E.NewBuilder("validate error")
func ValidateWithFieldTags(s any) gperr.Error {
errs := gperr.NewBuilder("validate error")
err := validate.Struct(s)
var valErrs validator.ValidationErrors
if errors.As(err, &valErrs) {
@ -107,13 +107,13 @@ func ValidateWithFieldTags(s any) E.Error {
return errs.Error()
}
func ValidateWithCustomValidator(v reflect.Value) E.Error {
func ValidateWithCustomValidator(v reflect.Value) gperr.Error {
isStruct := false
for {
switch v.Kind() {
case reflect.Pointer, reflect.Interface:
if v.IsNil() {
return E.Errorf("validate: v is %w", ErrNilValue)
return gperr.Errorf("validate: v is %w", ErrNilValue)
}
if validate, ok := v.Interface().(CustomValidator); ok {
return validate.Validate()
@ -134,14 +134,14 @@ func ValidateWithCustomValidator(v reflect.Value) E.Error {
}
}
func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err E.Error) {
func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err gperr.Error) {
dstT := dst.Type()
for {
switch dst.Kind() {
case reflect.Pointer, reflect.Interface:
if dst.IsNil() {
if !dst.CanSet() {
err = E.Errorf("dive: dst is %w and is not settable", ErrNilValue)
err = gperr.Errorf("dive: dst is %w and is not settable", ErrNilValue)
return
}
dst.Set(New(dstT.Elem()))
@ -158,7 +158,7 @@ func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err E.Error) {
case reflect.Slice:
dst.Set(reflect.MakeSlice(dstT, 0, 0))
default:
err = E.Errorf("deserialize: %w for dst %s", ErrInvalidType, dstT.String())
err = gperr.Errorf("deserialize: %w for dst %s", ErrInvalidType, dstT.String())
return
}
}
@ -180,7 +180,7 @@ func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err E.Error) {
// If the target value is a map[string]any the SerializedObject will be deserialized into the map.
//
// The function returns an error if the target value is not a struct or a map[string]any, or if there is an error during deserialization.
func Deserialize(src SerializedObject, dst any) (err E.Error) {
func Deserialize(src SerializedObject, dst any) (err gperr.Error) {
dstV := reflect.ValueOf(dst)
dstT := dstV.Type()
@ -189,7 +189,7 @@ func Deserialize(src SerializedObject, dst any) (err E.Error) {
dstV.Set(reflect.Zero(dstT))
return nil
}
return E.Errorf("deserialize: src is %w and dst is not settable\n%s", ErrNilValue, debug.Stack())
return gperr.Errorf("deserialize: src is %w and dst is not settable\n%s", ErrNilValue, debug.Stack())
}
if dstT.Implements(mapUnmarshalerType) {
@ -209,7 +209,7 @@ func Deserialize(src SerializedObject, dst any) (err E.Error) {
// convert target fields to lower no-snake
// then check if the field of data is in the target
errs := E.NewBuilder("deserialize error")
errs := gperr.NewBuilder("deserialize error")
switch dstV.Kind() {
case reflect.Struct, reflect.Interface:
@ -302,9 +302,9 @@ func isIntFloat(t reflect.Kind) bool {
//
// Returns:
// - error: the error occurred during conversion, or nil if no error occurred.
func Convert(src reflect.Value, dst reflect.Value) E.Error {
func Convert(src reflect.Value, dst reflect.Value) gperr.Error {
if !dst.IsValid() {
return E.Errorf("convert: dst is %w", ErrNilValue)
return gperr.Errorf("convert: dst is %w", ErrNilValue)
}
if !src.IsValid() {
@ -312,7 +312,7 @@ func Convert(src reflect.Value, dst reflect.Value) E.Error {
dst.Set(reflect.Zero(dst.Type()))
return nil
}
return E.Errorf("convert: src is %w", ErrNilValue)
return gperr.Errorf("convert: src is %w", ErrNilValue)
}
srcT := src.Type()
@ -379,7 +379,7 @@ func Convert(src reflect.Value, dst reflect.Value) E.Error {
if dstT.Kind() != reflect.Slice {
return ErrUnsupportedConversion.Subject(dstT.String() + " to " + srcT.String())
}
sliceErrs := E.NewBuilder("slice conversion errors")
sliceErrs := gperr.NewBuilder("slice conversion errors")
newSlice := reflect.MakeSlice(dstT, src.Len(), src.Len())
i := 0
for j, v := range src.Seq2() {
@ -401,7 +401,7 @@ func Convert(src reflect.Value, dst reflect.Value) E.Error {
return ErrUnsupportedConversion.Subjectf("%s to %s", srcT, dstT)
}
func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.Error) {
func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gperr.Error) {
convertible = true
dstT := dst.Type()
if dst.Kind() == reflect.Ptr {
@ -423,7 +423,7 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.E
}
d, err := time.ParseDuration(src)
if err != nil {
return true, E.From(err)
return true, gperr.Wrap(err)
}
dst.Set(reflect.ValueOf(d))
return
@ -443,14 +443,14 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.E
i, err = strconv.ParseFloat(src, dstT.Bits())
}
if err != nil {
return true, E.From(err)
return true, gperr.Wrap(err)
}
dst.Set(reflect.ValueOf(i).Convert(dstT))
return
}
// check if (*T).Convertor is implemented
if parser, ok := dst.Addr().Interface().(strutils.Parser); ok {
return true, E.From(parser.Parse(src))
return true, gperr.Wrap(parser.Parse(src))
}
// yaml like
var tmp any
@ -462,7 +462,7 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.E
if !isMultiline && src[0] != '-' {
values := strutils.CommaSeperatedList(src)
dst.Set(reflect.MakeSlice(dst.Type(), len(values), len(values)))
errs := E.NewBuilder("invalid slice values")
errs := gperr.NewBuilder("invalid slice values")
for i, v := range values {
err := Convert(reflect.ValueOf(v), dst.Index(i))
if err != nil {
@ -477,14 +477,14 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.E
sl := make([]any, 0)
err := yaml.Unmarshal([]byte(src), &sl)
if err != nil {
return true, E.From(err)
return true, gperr.Wrap(err)
}
tmp = sl
case reflect.Map, reflect.Struct:
rawMap := make(SerializedObject)
err := yaml.Unmarshal([]byte(src), &rawMap)
if err != nil {
return true, E.From(err)
return true, gperr.Wrap(err)
}
tmp = rawMap
default:
@ -493,17 +493,17 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.E
return true, Convert(reflect.ValueOf(tmp), dst)
}
func DeserializeYAML[T any](data []byte, target *T) E.Error {
func DeserializeYAML[T any](data []byte, target *T) gperr.Error {
m := make(map[string]any)
if err := yaml.Unmarshal(data, m); err != nil {
return E.From(err)
return gperr.Wrap(err)
}
return Deserialize(m, target)
}
func DeserializeYAMLMap[V any](data []byte) (_ functional.Map[string, V], err E.Error) {
func DeserializeYAMLMap[V any](data []byte) (_ functional.Map[string, V], err gperr.Error) {
m := make(map[string]any)
if err = E.From(yaml.Unmarshal(data, m)); err != nil {
if err = gperr.Wrap(yaml.Unmarshal(data, m)); err != nil {
return
}
m2 := make(map[string]V, len(m))

View file

@ -2,15 +2,15 @@ package utils
import (
"github.com/go-playground/validator/v10"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
)
var validate = validator.New()
var ErrValidationError = E.New("validation error")
var ErrValidationError = gperr.New("validation error")
type CustomValidator interface {
Validate() E.Error
Validate() gperr.Error
}
func Validator() *validator.Validate {

View file

@ -8,7 +8,7 @@ import (
"github.com/fsnotify/fsnotify"
"github.com/rs/zerolog"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/watcher/events"
@ -24,7 +24,7 @@ type DirWatcher struct {
mu sync.Mutex
eventCh chan Event
errCh chan E.Error
errCh chan gperr.Error
task *task.Task
}
@ -55,14 +55,14 @@ func NewDirectoryWatcher(parent task.Parent, dirPath string) *DirWatcher {
w: w,
fwMap: make(map[string]*fileWatcher),
eventCh: make(chan Event),
errCh: make(chan E.Error),
errCh: make(chan gperr.Error),
task: parent.Subtask("dir_watcher(" + dirPath + ")"),
}
go helper.start()
return helper
}
func (h *DirWatcher) Events(_ context.Context) (<-chan Event, <-chan E.Error) {
func (h *DirWatcher) Events(_ context.Context) (<-chan Event, <-chan gperr.Error) {
return h.eventCh, h.errCh
}
@ -78,7 +78,7 @@ func (h *DirWatcher) Add(relPath string) Watcher {
s = &fileWatcher{
relPath: relPath,
eventCh: make(chan Event),
errCh: make(chan E.Error),
errCh: make(chan gperr.Error),
}
h.fwMap[relPath] = s
return s
@ -162,7 +162,7 @@ func (h *DirWatcher) start() {
return
}
select {
case h.errCh <- E.From(err):
case h.errCh <- gperr.Wrap(err):
default:
}
}

View file

@ -7,7 +7,7 @@ import (
docker_events "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
"github.com/yusing/go-proxy/internal/docker"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/watcher/events"
)
@ -51,13 +51,13 @@ func NewDockerWatcher(host string) DockerWatcher {
return DockerWatcher{host: host}
}
func (w DockerWatcher) Events(ctx context.Context) (<-chan Event, <-chan E.Error) {
func (w *DockerWatcher) Events(ctx context.Context) (<-chan Event, <-chan gperr.Error) {
return w.EventsWithOptions(ctx, optionsDefault)
}
func (w DockerWatcher) EventsWithOptions(ctx context.Context, options DockerListOptions) (<-chan Event, <-chan E.Error) {
func (w *DockerWatcher) EventsWithOptions(ctx context.Context, options DockerListOptions) (<-chan Event, <-chan gperr.Error) {
eventCh := make(chan Event)
errCh := make(chan E.Error)
errCh := make(chan gperr.Error)
go func() {
defer func() {

View file

@ -5,7 +5,7 @@ import (
"time"
"github.com/yusing/go-proxy/internal/common"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/task"
)
@ -19,7 +19,7 @@ type (
onError OnErrorFunc
}
OnFlushFunc = func(events []Event)
OnErrorFunc = func(err E.Error)
OnErrorFunc = func(err gperr.Error)
)
const eventQueueCapacity = 10
@ -50,13 +50,13 @@ func NewEventQueue(queueTask *task.Task, flushInterval time.Duration, onFlush On
}
}
func (e *EventQueue) Start(eventCh <-chan Event, errCh <-chan E.Error) {
func (e *EventQueue) Start(eventCh <-chan Event, errCh <-chan gperr.Error) {
origOnFlush := e.onFlush
// recover panic in onFlush when in production mode
e.onFlush = func(events []Event) {
defer func() {
if err := recover(); err != nil {
e.onError(E.New("recovered panic in onFlush").
e.onError(gperr.New("recovered panic in onFlush").
Withf("%v", err).
Subject(e.task.Name()))
if common.IsDebug {

View file

@ -3,15 +3,15 @@ package watcher
import (
"context"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
)
type fileWatcher struct {
relPath string
eventCh chan Event
errCh chan E.Error
errCh chan gperr.Error
}
func (fw *fileWatcher) Events(ctx context.Context) (<-chan Event, <-chan E.Error) {
func (fw *fileWatcher) Events(ctx context.Context) (<-chan Event, <-chan gperr.Error) {
return fw.eventCh, fw.errCh
}

View file

@ -58,13 +58,9 @@ func (mon *monitor) ContextWithTimeout(cause string) (ctx context.Context, cance
}
// Start implements task.TaskStarter.
func (mon *monitor) Start(parent task.Parent) E.Error {
func (mon *monitor) Start(parent task.Parent) gperr.Error {
if mon.config.Interval <= 0 {
return E.From(ErrNegativeInterval)
}
if common.PrometheusEnabled {
mon.metric = metrics.GetServiceMetrics().HealthStatus.With(metrics.HealthMetricLabels(mon.service))
return gperr.Wrap(ErrNegativeInterval)
}
mon.service = parent.Name()

View file

@ -3,12 +3,12 @@ package watcher
import (
"context"
E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/watcher/events"
)
type Event = events.Event
type Watcher interface {
Events(ctx context.Context) (<-chan Event, <-chan E.Error)
Events(ctx context.Context) (<-chan Event, <-chan gperr.Error)
}