From 27b95b4911da055fe9b5fb37b5fb4a33eda6b989 Mon Sep 17 00:00:00 2001 From: Jeroen Wijenbergh Date: Mon, 25 Aug 2025 10:59:37 +0200 Subject: All: Remove util packages Was giving linting errors and it's not a good idea anyways --- i18nerr/i18nerr.go | 168 ----------------------------------------------------- 1 file changed, 168 deletions(-) delete mode 100644 i18nerr/i18nerr.go (limited to 'i18nerr') diff --git a/i18nerr/i18nerr.go b/i18nerr/i18nerr.go deleted file mode 100644 index 8254dd4..0000000 --- a/i18nerr/i18nerr.go +++ /dev/null @@ -1,168 +0,0 @@ -// Package i18nerr implements errors with internationalization using gotext -package i18nerr - -import ( - "context" - "errors" - "fmt" - "log/slog" - "sync" - - "codeberg.org/eduVPN/eduvpn-common/internal/http" - - "golang.org/x/text/language" - "golang.org/x/text/message" -) - -var ( - printers sync.Map - once sync.Once -) - -// TranslatedInner defines errors that are used as inner causes but are still translated because they can happen frequently -func TranslatedInner(inner error) (string, bool) { - unwrapped := inner - for errors.Unwrap(unwrapped) != nil { - unwrapped = errors.Unwrap(unwrapped) - } - - var tErr *http.TimeoutError - switch { - case errors.As(inner, &tErr): - return printerOrNew(language.English).Sprintf("Timeout reached contacting URL: '%s'", tErr.URL), false - case errors.Is(inner, context.Canceled): - return unwrapped.Error(), true - } - return unwrapped.Error(), false -} - -// Error wraps an actual error with the translation key -// This translation key is later used to lookup translation -// The inner error always consists of the translation key and some formatting -type Error struct { - key message.Reference - args []any - wrapped *Error - Misc bool -} - -func (e *Error) translated(t language.Tag) string { - once.Do(func() { - inititializeLangs() - }) - msg := printerOrNew(t).Sprintf(e.key, e.args...) - if e.wrapped != nil { - return printerOrNew(t).Sprintf("%s. The cause of the error is: %s.", msg, e.wrapped.Error()) - } - return msg -} - -// Error gets the error string -// it does this by simply forwarding the error method from the actual inner error -func (e *Error) Error() string { - return e.translated(language.English) -} - -// Translations returns all the translations for the error including the source translation (english) -func (e *Error) Translations() map[string]string { - translations := make(map[string]string) - // add the source transltaion first - source := e.Error() - translations[language.English.String()] = source - for _, t := range message.DefaultCatalog.Languages() { - // already added - if t == language.English { - continue - } - // get the final translation string for the tag - // and add it if it's not equal to the english version - f := e.translated(t) - if f != source { - translations[t.String()] = f - } - } - return translations -} - -// Unwrap returns the unwrapped error -// it does this by unwrapping the inner error -func (e *Error) Unwrap() error { - if e.wrapped == nil { - return nil - } - return e.wrapped.Unwrap() -} - -// printerOrNew gets a message printer from the global printers map using the tag 'tag' -// If the printer cannot be found in the sync map, we return a new printer -func printerOrNew(tag language.Tag) *message.Printer { - v, ok := printers.Load(tag) - if !ok { - slog.Debug("i18n could not load printer from map", "tag", tag) - return message.NewPrinter(tag) - } - p, ok := v.(*message.Printer) - if !ok { - slog.Debug("i18n could not load printer from map with incorrect type", "tag", tag, "type", fmt.Sprintf("%T", p)) - return message.NewPrinter(tag) - } - return p -} - -// New creates a new i18n error using a message reference -func New(key message.Reference) *Error { - _ = printerOrNew(language.English).Sprint(key) - return &Error{key: key} -} - -// Newf creates a new i18n error using a message reference and arguments. -// It formats this with fmt.Errorf -func Newf(key message.Reference, args ...any) *Error { - _ = printerOrNew(language.English).Sprintf(key, args...) - return &Error{key: key, args: args} -} - -// Wrap creates a new i18n error using an error to be wrapped 'err' and a prefix message reference 'key'. -// It formats this with fmt.Errorf -func Wrap(err error, key message.Reference) *Error { - _ = printerOrNew(language.English).Sprintf(key) - t, misc := TranslatedInner(err) - return &Error{key: key, wrapped: &Error{key: t, Misc: misc}, Misc: misc} -} - -// Wrapf creates a new i18n error using an error to be wrapped 'err' and a prefix message reference 'key' with format arguments 'args'. -// It formats this with fmt.Errorf -func Wrapf(err error, key message.Reference, args ...any) *Error { - _ = printerOrNew(language.English).Sprintf(key, args...) - t, misc := TranslatedInner(err) - return &Error{key: key, args: args, wrapped: &Error{key: t, Misc: misc}, Misc: misc} -} - -// NewInternal creates an internal localised error from a display string -func NewInternal(disp string) *Error { - return Wrap(errors.New(disp), "An internal error occurred") -} - -// NewInternalf creates an internal localised error from a display string and arguments -func NewInternalf(disp string, args ...any) *Error { - return NewInternal(fmt.Sprintf(disp, args...)) -} - -// WrapInternal wraps an error and a display string into a localised internal error -func WrapInternal(err error, disp string) *Error { - return Wrap(fmt.Errorf("%s with internal cause: %w", disp, err), "An internal error occurred") -} - -// WrapInternalf wraps an error and a display string with args into a localised internal error -func WrapInternalf(err error, disp string, args ...any) *Error { - return WrapInternal(err, fmt.Sprintf(disp, args...)) -} - -// initializeLangs initializes the printers from the default catalog into the sync map -// we cannot do this in init() because this is too early -func inititializeLangs() { - slog.Debug("i18n initializing languages") - for _, t := range message.DefaultCatalog.Languages() { - printers.Store(t, message.NewPrinter(t)) - } -} -- cgit v1.2.3