Errs module

master
dev 9 months ago
commit b91e6546af

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,7 @@
<component name="ProjectDictionaryState">
<dictionary name="project">
<words>
<w>segs</w>
</words>
</dictionary>
</component>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/FWS.iml" filepath="$PROJECT_DIR$/.idea/FWS.iml" />
</modules>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

@ -0,0 +1,3 @@
module apperrs
go 1.25

@ -0,0 +1,86 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero main.go
Package apperrs
Autor Juan V. Navarro juanvnl@activething.com
Creado 07/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package main
import (
"errors"
"errs"
"fmt"
"os"
)
func main() {
baseErr := errs.Code("auth::err_auth")
err := errs.WithMessage(
errs.WithCause(
errs.WithSeverity(
errs.WithStack(baseErr),
errs.SeverityCritical,
),
errors.New("db error"),
),
"authentication failed",
)
errs.NewTree(err).Print(os.Stdout)
otro := errs.Add(
errs.Code("::Mi_otro_error"),
errs.AddMessage("Esto es mi mengage"),
errs.AddUser("usuarion_anonimo"),
errs.AddStack(),
errs.AddCauses(errs.Code("::error_cause")))
errs.NewTree(otro).Print(os.Stdout)
fmt.Printf("%#v\n", errs.NewTree(err))
}

@ -0,0 +1,141 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero a.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 06/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import (
"errors"
"fmt"
"regexp"
)
const (
RootModule Module = Module("")
ErrsModule Module = Module("errs")
)
var (
// Global sentinels (no module prefix)
ErrNilError = RootModule.Code("nil-error")
ErrNilCause = RootModule.Code("nil-cause")
// Internal sentinels (errs module)
ErrInvalidModule = ErrsModule.Code("invalid-module")
ErrInvalidCode = ErrsModule.Code("invalid-severity")
ErrInvalidMetaName = ErrsModule.Code("invalid-meta-name")
ErrInvalidParamName = ErrsModule.Code("invalid-param-name")
paramRgx = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_]{0,62}[a-zA-Z0-9]$`)
metaRgx = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_-]{0,62}[a-zA-Z0-9_]$`)
codeRgx = regexp.MustCompile(`^[a-zA-Z0-9](?:[a-zA-Z0-9_-]*[a-zA-Z0-9])?$`)
severityName = []string{"UNKNOWN", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "FATAL"}
)
func isValidSegment(code string) bool { return len(code) > 0 && codeRgx.MatchString(code) }
func ToError(err any) error {
if err == nil {
return nil
}
switch t := err.(type) {
case error:
return t
case []error:
return MakeMultiError(t)
default:
return fmt.Errorf("%v", err)
}
}
func ToString(err error) string {
if err == nil {
return ""
}
switch e := err.(type) {
case Code:
return string(e)
case *Code:
return string(*e)
case fmt.Stringer:
return e.String()
default:
return err.Error()
}
}
func Matches(err, target error) bool {
var t Code
if !errors.As(target, &t) {
return false
}
// Itera por toda la cadena de unwrap
for e := err; e != nil; e = errors.Unwrap(e) {
var c Code
if errors.As(e, &c) && c.IsOrFrom(t) {
return true
}
}
return false
}
func IsSubOf(parent, err error) bool {
var p Code
if !errors.As(parent, &p) {
return false
}
for e := err; e != nil; e = errors.Unwrap(e) {
var c Code
if errors.As(e, &c) && c.IsSubOf(p) {
return true
}
}
return false
}

@ -0,0 +1,80 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero adder.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
type (
Adder interface {
Add(err error) error
}
AddFnc func(err error) error
)
func (f AddFnc) Add(err error) error { return f(err) }
func Add(base error, composers ...Adder) error {
if base == nil {
// Panics with a specific error if the base error is nil, indicating incorrect usage.
panic(MakePanicError(ErrNilError))
}
if len(composers) == 0 {
return base
}
// Apply each composer sequentially.
for _, c := range composers {
if c != nil {
// If the composer returns a new non-nil error, update the base error.
if nb := c.Add(base); nb != nil {
base = nb
}
}
}
return base
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,54 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero causer.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 15/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
type Causer interface {
Cause() error
}

@ -0,0 +1,54 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero causers.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 15/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
type Causers interface {
Causes() []error
}

@ -0,0 +1,138 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero severity.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 03/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import (
"errors"
"strings"
)
type Code string
func (c Code) Sub(newCode string) Code { return makeCode(string(c), CodeSep, newCode) }
func (c Code) Module() Module {
s := string(c)
if i := strings.Index(s, ModuleSep); i != -1 {
return Module(s[:i])
}
return RootModule
}
func (c Code) Leaf() string {
s := string(c)
if i := strings.LastIndex(s, CodeSep); i >= 0 {
return string(c[i+lenCodeSep:])
}
if i := strings.Index(s, ModuleSep); i != -1 {
return s[i+lenModuleSep:]
}
return s
}
func (c Code) Parent() Code {
if i := strings.LastIndex(string(c), CodeSep); i >= 0 {
return c[:i]
}
return ""
}
func (c Code) Segs() []string {
s := string(c)
n := len(s)
var segments []string
// encontrar módulo
moduleEnd := strings.Index(s, ModuleSep)
if moduleEnd == -1 || moduleEnd+lenModuleSep >= n {
return []string{s} // solo módulo o cadena simple
}
segments = append(segments, s[:moduleEnd])
// iterar sobre el resto de la cadena
start := moduleEnd + lenModuleSep
for i := start; i <= n; i++ {
if i == n || s[i] == CodeSep[0] {
segments = append(segments, s[start:i])
start = i + 1
}
}
return segments
}
func (c Code) IsSubOf(parent error) bool {
var p Code
if !errors.As(parent, &p) {
return false
}
s, ps := string(c), string(p)
if s == ps {
return false
}
return strings.HasPrefix(s, ps+CodeSep)
}
func (c Code) Is(target error) bool {
var t Code
return errors.As(target, &t) && c == t
}
func (c Code) IsOrFrom(target error) bool {
var t Code
if !errors.As(target, &t) {
return false
}
sc := string(c)
st := string(t)
return sc == st || strings.HasPrefix(sc, st+CodeSep)
}
func (c Code) Error() string { return string(c) }
func (c Code) String() string { return string(c) }

@ -0,0 +1,60 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero collectable.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 20/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
type (
Collectable interface {
Collect(collector Collector)
}
CollectFnc func(collector Collector)
)
func (f CollectFnc) Collect(collector Collector) { f(collector) }

@ -0,0 +1,58 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero collector.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 20/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
type Collector interface {
Options() CollectorFlags
AddMetas(meta ...Meta)
AddCauses(causes ...error)
AddStack(stack Stack)
}

@ -0,0 +1,79 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero meta_filter.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 15/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const (
CollectorFlagMetas CollectorFlags = 1 << iota
CollectorFlagCauses
CollectorFlagStack
CollectorFlagEmpty
CollectorFlagsAll = (1 << iota) - 1
)
// CollectorOptss is a bitmask type used to select which types of metadata to retrieve.
type CollectorFlags uint8
// CanAcceptMetas returns true if the CollectorOptss includes the MetaFilterField flag.
func (s CollectorFlags) HasMetas() bool { return s&CollectorFlagMetas != 0 }
// HasCauses returns true if the CollectorOptss includes the MetaFilterCause flag.
func (s CollectorFlags) HasCauses() bool { return s&CollectorFlagCauses != 0 }
// HasStack returns true if the CollectorOptss includes the MetaFilterStack flag.
func (s CollectorFlags) HasStack() bool { return s&CollectorFlagStack != 0 }
func (s CollectorFlags) HasEmpty() bool { return s&CollectorFlagEmpty != 0 }
func (s CollectorFlags) Can(flag CollectorFlags) bool { return s&flag != 0 }
func (s CollectorFlags) Del(flag CollectorFlags) CollectorFlags { return s &^ flag }
func (s CollectorFlags) Add(flag CollectorFlags) CollectorFlags { return s | flag }

@ -0,0 +1,122 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero error_list.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 09/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
type ErrorList []error
func (l ErrorList) Any() bool {
for _, e := range l {
if e != nil {
return true
}
}
return false
}
func (l ErrorList) Count() int {
c := 0
for _, e := range l {
if e != nil {
c++
}
}
return c
}
func (l ErrorList) First() error {
for _, e := range l {
if e != nil {
return e
}
}
return nil
}
func (l ErrorList) Last() error {
for i := len(l) - 1; i >= 0; i-- {
if l[i] != nil {
return l[i]
}
}
return nil
}
func (l ErrorList) Append(err error) ErrorList {
return append(l, err)
}
// AppendNotNil adds an error to the list only if it's not nil.
// Returns the modified error list or the original list if the error was nil.
func (l ErrorList) AppendNotNil(err error) ErrorList {
if err != nil {
return append(l, err)
}
return l
}
func (l ErrorList) Reset() ErrorList {
return l[:0]
}
func (l ErrorList) filter(filter func(error) bool) ErrorList {
rs := make([]error, 0, len(l))
for _, e := range l {
if filter(e) {
rs = append(rs, e)
}
}
return rs
}
func (l ErrorList) Clean() ErrorList {
return l.filter(func(e error) bool {
return e != nil
})
}

@ -0,0 +1,63 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero format.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 19/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import (
"io"
)
func format(w io.Writer, err error, level int, ops FormatOptions) error {
if err == nil {
return nil
}
//todo
return nil
}

@ -0,0 +1,171 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero format_flags.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 19/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import (
"fmt"
"strings"
)
const (
// FormatShowHierarchy is a flag to show the error hierarchy (wrapped errors/causes).
FormatShowHierarchy FormatterFlags = 1 << iota
// FormatShowMetas is a flag to show metadata of the current error in the hierarchy.
FormatShowMetas
// FormatShowDeepMetas is a flag to show metadata for all errors in the hierarchy.
FormatShowDeepMetas
// FormatShowStack is a flag to show the stack trace of the root error.
FormatShowStack
// FormatShowDeepStacks is a flag to show stack traces for all errors in the hierarchy if defined.
FormatShowDeepStacks
// FormatShowAll is a convenience flag to show everything.
FormatShowAll = (1 << iota) - 1
// FormatShowNone is a flag to show nothing extra (only the basic error message).
FormatShowNone FormatterFlags = 0
)
type (
// FormatterFlags is a bitmask type used to control which parts of an error are displayed during formatting.
FormatterFlags uint8
)
// HasMetas returns true if the FormatterFlags includes the FormatShowMetas flag.
func (o FormatterFlags) HasMetas() bool { return o&FormatShowMetas != 0 }
// HasHierarchy returns true if the FormatterFlags includes the FormatShowHierarchy flag.
func (o FormatterFlags) HasHierarchy() bool { return o&FormatShowHierarchy != 0 }
// HasDeepMetas returns true if the FormatterFlags includes the FormatShowDeepMetas flag.
func (o FormatterFlags) HasDeepMetas() bool { return o&FormatShowDeepMetas != 0 }
// HasStack returns true if the FormatterFlags includes the FormatShowStack flag.
func (o FormatterFlags) HasStack() bool { return o&FormatShowStack != 0 }
// HasDeepStacks returns true if the FormatterFlags includes the FormatShowDeepStacks flag.
func (o FormatterFlags) HasDeepStacks() bool { return o&FormatShowDeepStacks != 0 }
func (o FormatterFlags) IsDeepMode() bool { return o.HasDeepMetas() || o.HasDeepStacks() }
func (o FormatterFlags) IsMinimal() bool { return o == FormatShowNone }
func (o FormatterFlags) Normalize() FormatterFlags {
// Si HasDeepMetas está activo, HasMetas también debería estarlo
if o.HasDeepMetas() {
o |= FormatShowMetas
}
if o.HasDeepStacks() {
o |= FormatShowStack
}
return o
}
// String returns a human-readable representation of the FormatterFlags flags.
func (o FormatterFlags) String() string {
if o == FormatShowNone {
return "none"
}
var parts []string
if o.HasHierarchy() {
parts = append(parts, "hierarchy")
}
if o.HasMetas() {
if o.HasDeepMetas() {
parts = append(parts, "deep-metas")
} else {
parts = append(parts, "metas")
}
}
if o.HasStack() {
if o.HasDeepStacks() {
parts = append(parts, "deep-stacks")
} else {
parts = append(parts, "stack")
}
}
return strings.Join(parts, "|")
}
// FormatFlagsFromVerb derives FormatterFlags flags based on the fmt.State and verb.
// This function interprets standard fmt verbs and flags to determine what to display.
func FormatFlagsFromVerb(f fmt.State, verb rune) FormatterFlags {
s := FormatShowNone
switch verb {
case 'v':
// For %v, check flags to determine what to show.
if f.Flag('+') {
// %+v -> Show hierarchy, metas, and full stack
s = FormatShowAll
} else if f.Flag('#') {
// %#v -> Show metas and stack of the principal error
s |= FormatShowMetas | FormatShowStack
} else if f.Flag('-') {
s |= FormatShowHierarchy | FormatShowMetas
} else {
// %v -> Show hierarchy and principal stack (optional based on your criterion)
s |= FormatShowHierarchy | FormatShowStack
}
/*
case 's', 'q':
case 'd', 'o', 'x', 'X':
*/
default:
return s
}
return s.Normalize()
}

@ -0,0 +1,75 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero format_options.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 19/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
type (
FormatOptions struct {
Flags FormatterFlags
EnableColor bool
Indent string
FmtError string
FmtMeta string
FmtCause string
FmtStackHead string
FmtStackLine string
}
)
func NewFormatOptions() *FormatOptions {
return &FormatOptions{
Indent: " ",
FmtError: "%s%s\n",
FmtMeta: "%s * %s: %v\n",
FmtCause: "%s%s\n",
FmtStackHead: "%s * stack:\n",
FmtStackLine: "%s %s\n",
}
}

@ -0,0 +1,62 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero formatter.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 19/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import "io"
type (
Formatter interface {
Format(writer io.Writer, err error) error
}
FormatFnc func(writer io.Writer, err error) error
)
func (f FormatFnc) Format(writer io.Writer, err error) error { return f(writer, err) }

@ -0,0 +1,3 @@
module errs
go 1.25

@ -0,0 +1,78 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero meta.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 15/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
type Meta interface {
Name() string
Value() any
}
type meta struct {
name string
value any
}
func MakeMeta(name string, value any) Meta {
if len(name) == 0 || !metaRgx.MatchString(name) {
panic(MakePanicError(ErrInvalidMetaName))
}
return &meta{
name: name,
value: value,
}
}
func (m meta) Name() string { return m.name }
func (m meta) Value() any { return m.value }
func IsValidMetaName(meta string) bool {
return len(meta) > 0 && metaRgx.MatchString(meta)
}

@ -0,0 +1,77 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero module.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 06/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const (
CodeSep = "."
ModuleSep = "::"
lenModuleSep = 2
lenCodeSep = 1
)
type Module string
func MakeModule(name string) Module {
if !isValidSegment(name) {
panic(ErrInvalidModule)
}
return Module(name)
}
func (m Module) Code(code string) Code { return makeCode(string(m), ModuleSep, code) }
func (m Module) String() string { return string(m) }
func makeCode(parent string, sep string, code string) Code {
if !isValidSegment(code) {
panic(ErrInvalidCode)
}
return Code(parent + sep + code)
}

@ -0,0 +1,110 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero multi_error.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 09/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import (
"errors"
)
const CodeMultiError = Code(ModuleSep + "multi_error")
type MultiError struct {
Code
ErrorList
}
func MakeMultiError(causes ErrorList) MultiError {
return MultiError{
Code: CodeMultiError,
ErrorList: causes.Clean()}
}
// FindIs encuentra el primer error en la lista para el que errors.Is devuelve true.
// Devuelve el error encontrado o nil si ninguno coincide.
//
// Ejemplo:
//
// if found := multi.FindIs(SomeCode); found != nil {
// fmt.Println("Encontrado error de esa categoría:", found)
// }
func (w MultiError) FindIs(target error) error {
for _, e := range w.ErrorList {
if errors.Is(e, target) {
return e
}
}
return nil
}
func (w MultiError) Is(target error) bool { return w.FindIs(target) != nil || Matches(w, target) }
// FindAs encuentra el primer error en la lista que coincide con target.
// target debe ser un puntero a un tipo que implemente error o una interfaz.
// Devuelve el error encontrado o nil si no se encuentra.
func (w MultiError) FindAs(target any) error {
for _, err := range w.ErrorList {
if errors.As(err, target) {
return err
}
}
return nil
}
func (w MultiError) Unwrap() []error { return w.ErrorList }
// Meta interface implementación
func (w MultiError) Name() string { return MetaCauseName }
func (w MultiError) Value() any { return w.ErrorList }
func (w MultiError) Collect(collector Collector) {
if collector.Options().HasCauses() {
collector.AddCauses(w.ErrorList...)
}
}

@ -0,0 +1,76 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero panic_error.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 08/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const (
CodePanic = Code(ModuleSep + "panic")
)
type PanicError struct {
Code
cause error
}
func MakePanicError(cause any) PanicError {
return PanicError{
Code: CodePanic,
cause: ToError(cause),
}
}
func (c PanicError) Unwrap() error { return c.cause }
func (c PanicError) Cause() error { return c.cause }
func (c PanicError) Collect(collector Collector) {
if collector.Options().HasCauses() {
collector.AddCauses(c.Cause())
}
}

@ -0,0 +1,120 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero param_error.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 08/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const (
CodeParamError = Code(ModuleSep + "invalid_param")
CodeParamNilError = CodeParamError + CodeSep + "nil"
CodeParamEmptyError = CodeParamError + CodeSep + "empty"
CodeParamTypeError = CodeParamError + CodeSep + "invalid_type"
CodeParamFormatError = CodeParamError + CodeSep + "invalid_format"
CodeParamRangeError = CodeParamError + CodeSep + "range"
CodeParamRangeMinError = CodeParamRangeError + CodeSep + "min"
CodeParamRangeMaxError = CodeParamRangeError + CodeSep + "max"
MetaParamName = "param_name"
MetaParamValue = "param_value"
)
type ParamError struct {
Code
param string
value any
}
func MakeParamError(param string, value any) ParamError {
if len(param) == 0 || !paramRgx.MatchString(param) {
panic(MakePanicError(ErrInvalidParamName))
}
return ParamError{
Code: CodeParamError,
param: param,
value: value}
}
func MakeParamNilError(param string) ParamError {
return ParamError{Code: CodeParamNilError, param: param}
}
func MakeParamEmptyError(param string) ParamError {
return ParamError{Code: CodeParamEmptyError, param: param}
}
func MakeParamTypeError(param string) ParamError {
return ParamError{Code: CodeParamTypeError, param: param}
}
func MakeParamFormatError(param string, value any) ParamError {
return ParamError{Code: CodeParamFormatError, param: param, value: value}
}
func MakeParamRangeError(param string, value any) ParamError {
return ParamError{Code: CodeParamRangeError, param: param, value: value}
}
func MakeParamRangeMinError(param string, value any) ParamError {
return ParamError{Code: CodeParamRangeMinError, param: param, value: value}
}
func MakeParamRangeMaxError(param string, value any) ParamError {
return ParamError{Code: CodeParamRangeMaxError, param: param, value: value}
}
func (e ParamError) Param() string { return e.param }
func (e ParamError) Value() any { return e.value }
func (e ParamError) Collect(collector Collector) {
if collector.Options().HasMetas() {
collector.AddMetas(
MakeMeta(MetaParamName, e.param),
MakeMeta(MetaParamValue, e.value))
}
}

@ -0,0 +1,81 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero severity.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const (
// SeverityDebug indicates a severity level for debugging information.
SeverityDebug Severity = 1 + iota
// SeverityInfo indicates a severity level for general information.
SeverityInfo
// SeverityWarn indicates a severity level for warnings.
SeverityWarn
// SeverityError indicates a severity level for errors affecting functionality.
SeverityError
// SeverityCritical indicates a severity level for critical errors requiring immediate attention.
SeverityCritical
// SeverityFatal indicates a severity level for errors causing application termination.
SeverityFatal
)
// Severity represents the severity level of an error.
// It is used to classify the importance of an error.
type Severity uint8
// String returns the string representation of the severity level.
// Returns "UNKNOWN" for undefined severity values.
func (s Severity) String() string {
// Checks if the severity value is within the expected range.
if s <= 0 || s > SeverityFatal {
return severityName[0]
}
// Uses a string slice to map the severity value to its name.
// Note: Index 0 is not used as severity values start from 1 (1 << 0).
return severityName[s]
}

@ -0,0 +1,113 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero stack.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import (
"runtime"
)
// Constants used for stack trace configuration and handling.
const (
// stackSkipFrames defines how many initial frames are skipped when capturing the stack.
// 2 frames are skipped to exclude internal system calls (runtime.Callers and this function).
stackSkipFrames = 2
// stackMaxFrames defines the maximum number of frames that will be captured.
// Limits the depth of the stack trace to 32 frames by default.
stackMaxFrames = 32
)
// Stack is a slice of program counters, representing a captured stack trace.
type Stack []uintptr
// CreateStack captures the current execution stack trace.
// It takes an offset (number of frames to skip in addition to the default)
// and maxFrames (maximum number of frames to capture).
// Returns a Stack slice containing the captured program counters.
func CreateStack(options ...int) Stack {
offset := 0
maxFrames := stackMaxFrames
if len(options) > 0 {
offset = options[0]
if offset < 0 {
offset = 0
}
if len(options) > 1 {
maxFrames = options[1]
if maxFrames < 0 || maxFrames > stackMaxFrames {
maxFrames = stackMaxFrames
}
}
}
ls := make([]uintptr, maxFrames)
// Capture the stack trace using runtime.Callers.
// runtime.Callers fills the slice 'ls' with program counters,
// skipping 'offset + stackSkipFrames' frames.
// 'cn' will contain the actual number of frames captured.
cn := runtime.Callers(offset+stackSkipFrames, ls)
// Return only the slice containing valid program counters (up to 'cn').
return ls[:cn]
}
// Frames converts the Stack (slice of program counters) into a slice of StackFrame objects.
// Each StackFrame provides detailed information about a single frame in the stack.
func (s Stack) Frames() []StackFrame {
// Create a slice to store StackFrame objects with the same length as the stack.
f := make([]StackFrame, len(s))
// Convert each program counter to a StackFrame object.
for i, p := range s {
f[i] = CreateStackFrame(p)
}
return f
}

@ -0,0 +1,165 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero stack_frame.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import (
"bufio"
"bytes"
"os"
"runtime"
"strings"
)
const (
// stackUnknownInfo is the default value when information about a stack frame cannot be obtained.
stackUnknownInfo = "???"
)
type (
// StackFrame represents a single frame in a stack trace.
// It contains detailed information about the function call at that point.
StackFrame struct {
// LineNumber is the line number in the source file where this frame was created.
LineNumber int
// File is the full path to the source file containing this frame.
File string
// FuncName is the name of the function where this frame was created,
// with any receiver types removed.
FuncName string
// Package is the full package path where this frame was created.
Package string
// Counter is the program counter address for this frame.
Counter uintptr
}
)
// CreateStackFrame creates a new StackFrame from a program counter address.
// It uses runtime information to populate the frame details.
// Returns an empty StackFrame if the counter is 0.
func CreateStackFrame(counter uintptr) StackFrame {
sf := StackFrame{}
if counter == 0 {
return sf
}
sf.Counter = counter
fn := runtime.FuncForPC(counter)
if fn == nil {
sf.FuncName = stackUnknownInfo
return sf
}
sf.Package, sf.FuncName = packageAndName(fn)
sf.File, sf.LineNumber = fn.FileLine(counter - 1)
return sf
}
// SourceLine attempts to retrieve the source severity line for this stack frame.
// It reads the source file and returns the content of the line specified by LineNumber.
// Returns stackUnknownInfo if the line number is invalid or an error occurs while reading the file.
func (f StackFrame) SourceLine() string {
if f.LineNumber <= 0 || f.File == "" {
return stackUnknownInfo
}
// 1. Verificación rápida: ¿Existe el archivo?
// Evita intentar abrir archivos que no existen (común en Docker/Prod).
if _, err := os.Stat(f.File); os.IsNotExist(err) {
return "" // Retorna vacío silenciosamente en lugar de "???" para no ensuciar logs.
}
// 2. Lectura segura
file, err := os.Open(f.File)
if err != nil {
return ""
}
defer func() { _ = file.Close() }()
scanner := bufio.NewScanner(file)
currentLine := 1
for scanner.Scan() {
if currentLine == f.LineNumber {
return string(bytes.TrimSpace(scanner.Bytes()))
}
currentLine++
// Optimización: Si pasamos la línea, dejar de leer.
if currentLine > f.LineNumber {
break
}
}
return stackUnknownInfo
}
// packageAndName extracts the package path and function name from a runtime.Func.
// It handles different naming conventions, including methods.
func packageAndName(fn *runtime.Func) (string, string) {
nm := fn.Name() // Get the full name, e.g., "main.(*MyType).MyMethod" or "main.myFunction"
pg := "" // Initialize package path
// Find the last slash, which separates package path components.
if ls := strings.LastIndex(nm, "/"); ls >= 0 {
pg = nm[:ls] + "/" // Extract the path part
nm = nm[ls+1:] // Keep the rest of the name
}
// Find the first dot after the last slash, which separates package name from function name.
if pd := strings.Index(nm, "."); pd >= 0 {
pg += nm[:pd] // Add the package name to the path
nm = nm[pd+1:] // Keep the function name
}
// Replace the Go internal method separator '·' with '.' for readability.
return pg, strings.Replace(nm, "·", ".", -1)
}

@ -0,0 +1,204 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero tree.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 20/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import (
"errors"
"fmt"
"io"
"strings"
)
const MaxDeep = 32
type (
Tree struct {
flags CollectorFlags
maxDeep int
level int
Err error
Causes []*Tree
Metas []Meta
Stack Stack
}
TreeFnc func(*Tree)
)
func NewTree(err error, ops ...TreeFnc) *Tree {
return newTree(err, 0)
}
func newTree(err error, level int) *Tree {
if err == nil || (level > MaxDeep) {
return nil
}
node := &Tree{
Err: err,
level: level,
maxDeep: MaxDeep,
flags: CollectorFlagsAll,
}
for e := err; e != nil; {
if c, ok := e.(Collectable); ok {
c.Collect(node)
}
e = errors.Unwrap(e)
}
return node
}
func (t *Tree) Options() CollectorFlags { return t.flags }
func (t *Tree) MaxDeep() int { return t.maxDeep }
// AddStack stores the first captured stack trace.
//
// Once a stack is set, further stack collection is disabled.
// This enforces a single authoritative stack trace per error,
// avoiding noise and preserving a clear origin.
func (t *Tree) AddStack(stack Stack) {
t.Stack = stack
t.flags = t.flags.Del(CollectorFlagStack)
}
func (t *Tree) AddMetas(meta ...Meta) { t.Metas = append(t.Metas, meta...) }
func (t *Tree) AddCauses(causes ...error) {
if !t.flags.HasCauses() {
return
}
for _, cause := range causes {
if cause == nil {
continue
}
if child := newTree(cause, t.level+1); child != nil {
t.Causes = append(t.Causes, child)
}
}
}
func (t *Tree) print(w io.Writer, prefix string, isLast bool) {
marker := "├── "
if isLast {
marker = "└── "
if t.level == 0 {
marker = "─── "
}
}
// Root error (use Error() for formatted)
fmt.Fprintf(w, "%s%s%v\n", prefix, marker, t.Err.Error()) // Use Error() not %v
childPrefix := prefix
if isLast {
childPrefix += " "
} else {
childPrefix += "│ "
}
// All Metas (current)
for i, meta := range t.Metas {
isLastMeta := i == len(t.Metas)-1 && len(t.Causes) == 0 && len(t.Stack) != 0
metaMarker := "├── "
if isLastMeta {
metaMarker = "└── "
}
fmt.Fprintf(w, "%s%s[%s: %v]\n", childPrefix, metaMarker, meta.Name(), meta.Value())
}
// Stack (current)
if len(t.Stack) != 0 {
isLastStack := len(t.Causes) == 0
stackMarker := "├── "
if isLastStack {
stackMarker = "└── "
}
frames := t.Stack.Frames()
fmt.Fprintf(w, "%s%s[stack: %d frames]\n", childPrefix, stackMarker, len(frames))
for i := 0; i < len(frames) && i < 3; i++ {
frame := frames[i]
fmt.Fprintf(w, "%s %s:%d %s\n", childPrefix, shortenPath(frame.File), frame.LineNumber, frame.FuncName)
}
}
// Recurse Causes (show full child)
for i, cause := range t.Causes {
isLastCause := i == len(t.Causes)-1
cause.print(w, childPrefix, isLastCause)
}
}
// shortenPath acorta rutas largas para mejor legibilidad
func shortenPath(path string) string {
parts := strings.Split(path, "/")
if len(parts) > 3 {
return ".../" + strings.Join(parts[len(parts)-2:], "/")
}
return path
}
func (t *Tree) Print(w io.Writer) {
if t == nil {
return
}
t.print(w, "", true)
}
// String implementa fmt.Stringer para print directo
func (t *Tree) String() string {
var buf strings.Builder
t.Print(&buf)
return buf.String()
}

@ -0,0 +1,90 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_cause.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 08/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const (
MetaCauseName = "cause"
)
type withCause struct {
error
cause error
}
func AddCause(cause error) Adder {
return AddFnc(func(err error) error { return WithCause(err, cause) })
}
func WithCause(err error, cause error) error {
if err == nil {
if cause != nil {
return cause
}
panic(MakePanicError(ErrNilError))
}
if cause == nil {
return err
}
return withCause{
error: err,
cause: cause,
}
}
func (w withCause) Unwrap() error { return w.error }
func (w withCause) Cause() error { return w.cause }
func (w withCause) Collect(c Collector) {
if c.Options().HasCauses() {
c.AddCauses(w.cause)
}
}

@ -0,0 +1,163 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_causes.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 15/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const MetaCausesName = "causes"
// withCauses is an internal wrapper that associates one or more *causal errors*
// to an error without changing its semantic identity.
//
// IMPORTANT DESIGN NOTES:
//
// - Causes are NOT part of the Go unwrap chain.
// - Causes do NOT represent "previous" errors in the sense of errors.Is / errors.As.
// - Causes are purely explanatory: they answer *why* an error occurred,
// not *what* error it is.
//
// Each withCauses instance owns ONLY the causes it introduces.
// Causes are NOT inherited, merged, or propagated from wrapped errors.
// This avoids duplication and ensures that causes appear exactly once
// when traversing the error chain.
//
// The wrapped `error` represents the semantic identity of the error
// and is the only value returned by Unwrap().
type withCauses struct {
error
causes ErrorList // Uses ErrorList to normalize, clean and manage cause lists
}
// AddCauses returns an Adder that attaches one or more causal errors to an error.
//
// This function is syntactic sugar around WithCauses, intended to be used
// in error composition pipelines.
//
// Causes added through this function are local to the wrapper created by
// WithCauses and are not propagated to inner errors.
func AddCauses(causes ...error) Adder {
return AddFnc(func(err error) error {
return WithCauses(err, causes...)
})
}
// WithCauses associates one or more causal errors to err.
//
// Conceptual model:
//
// - `err` represents the *identity* of the error (what failed).
// - `causes` represent the *explanation* (why it failed).
//
// Causes are NOT merged with existing causes in wrapped errors.
// Each call to WithCauses introduces a new causal layer that owns
// its causes exclusively.
//
// This design guarantees that:
// - causes are not duplicated when unwrapping errors
// - the causal graph remains stable and predictable
// - error identity and causality are clearly separated
//
// Behaviour:
// - If err is nil and causes are provided, a MultiError is created.
// - If err is nil and no causes are provided, the function panics.
// - If no valid causes remain after cleaning, err is returned unchanged.
// Example:
// err := errs.WithCauses(baseErr, io.EOF, os.ErrNotExist)
// // err identity = baseErr
// // err causes = [io.EOF, os.ErrNotExist]
// // errors.Is(err, baseErr) == true
// // errors.Is(err, io.EOF) == false (causes not in Is chain)
func WithCauses(err error, causes ...error) error {
lc := ErrorList(causes).Clean()
if err == nil {
if len(lc) > 0 {
return MakeMultiError(lc)
}
panic(MakePanicError(ErrNilError))
}
// No causes → no wrapper
if len(lc) == 0 {
return err
}
return withCauses{
error: err,
causes: lc,
}
}
// Causes returns the causal errors introduced by this wrapper.
//
// The returned causes are local to this withCauses instance and do not
// include causes from wrapped errors.
func (w withCauses) Causes() []error {
return w.causes
}
// Unwrap returns the semantic identity of the error.
//
// Causes are intentionally NOT part of the unwrap chain.
// This preserves compatibility with Go's errors.Is / errors.As mechanisms
// and keeps causality orthogonal to error identity.
func (w withCauses) Unwrap() error {
return w.error
}
// Collect exports the causes to the provided Collector if the collector
// is configured to accept causes.
//
// Cause collection is explicit and opt-in, reinforcing the idea that
// causality is not part of the implicit unwrap traversal.
func (w withCauses) Collect(c Collector) {
if c.Options().HasCauses() && len(w.causes) > 0 {
c.AddCauses(w.causes...)
}
}

@ -0,0 +1,91 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_date.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import (
"time"
)
const MetaDateName = "date"
type withDate struct {
error
date time.Time
}
func AddDate() Adder {
return AddFnc(WithDate)
}
func WithDate(err error) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
return withDate{
error: err,
date: time.Now(),
}
}
func (w withDate) Unwrap() error {
return w.error
}
func (w withDate) Date() time.Time { return w.date }
// Meta interface implementación
func (w withDate) Name() string { return MetaDateName }
func (w withDate) Value() any { return w.date }
func (w withDate) Collect(c Collector) {
if c.Options().HasMetas() {
c.AddMetas(w)
}
}

@ -0,0 +1,113 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_info.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const (
MetaInfoDescName = "desc"
MetaInfoHelpName = "help"
MetaInfoLinkName = "link"
)
type withInfo struct {
error // The wrapped error
desc string // A descriptive message about the error
help string // Text providing guidance on how to resolve the error
link string // A URL pointing to documentation related to the error
}
func AddInfo(desc, help, link string) Adder {
return AddFnc(func(e error) error { return WithInfo(e, desc, help, link) })
}
func WithInfo(err error, desc, help, link string) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
return withInfo{
error: err,
desc: desc,
help: help,
link: link,
}
}
// Desc returns the descriptive message about the error.
func (w withInfo) Desc() string { return w.desc }
// Help returns the help text for resolving the error.
func (w withInfo) Help() string { return w.help }
// Link returns the documentation link for the error.
func (w withInfo) Link() string { return w.link }
// Unwrap implements Go 1.13+'s errors.Unwrap interface.
// It returns the wrapped error.
func (w withInfo) Unwrap() error { return w.error }
func (w withInfo) Collect(collector Collector) {
if collector.Options().HasMetas() {
if collector.Options().HasEmpty() {
collector.AddMetas(
MakeMeta(MetaInfoDescName, w.desc),
MakeMeta(MetaInfoHelpName, w.help),
MakeMeta(MetaInfoLinkName, w.link))
return
}
if len(w.desc) > 0 {
collector.AddMetas(MakeMeta(MetaInfoDescName, w.desc))
}
if len(w.help) > 0 {
collector.AddMetas(MakeMeta(MetaInfoHelpName, w.help))
}
if len(w.link) > 0 {
collector.AddMetas(MakeMeta(MetaInfoLinkName, w.link))
}
}
}

@ -0,0 +1,93 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_message.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import "fmt"
const MetaMessageName = "message"
type withMessage struct {
error
message string
}
func AddMessage(message string, args ...any) Adder {
return AddFnc(func(err error) error { return WithMessage(err, message, args...) })
}
func WithMessage(err error, message string, args ...any) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
m := message
if len(args) > 0 {
m = fmt.Sprintf(message, args...)
}
return withMessage{
error: err,
message: m,
}
}
func (w withMessage) Unwrap() error {
return w.error
}
func (w withMessage) Message() string { return w.message }
// Meta interface implementación
func (w withMessage) Name() string { return MetaMessageName }
func (w withMessage) Value() any { return w.message }
func (w withMessage) Collect(collector Collector) {
if collector.Options().HasMetas() && (len(w.message) > 0 || collector.Options().HasEmpty()) {
collector.AddMetas(w)
}
}

@ -0,0 +1,84 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_metas.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
type withMetas struct {
error
metas []Meta
}
func AddMetas(metas ...Meta) Adder {
return AddFnc(func(err error) error { return WithMetas(err, metas...) })
}
func WithMetas(err error, metas ...Meta) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
if len(metas) == 0 {
return err
}
return withMetas{
error: err,
metas: metas,
}
}
func (w withMetas) Metas() []Meta { return w.metas }
func (w withMetas) Unwrap() error {
return w.error
}
func (w withMetas) Collect(collector Collector) {
if collector.Options().HasMetas() {
collector.AddMetas(w.metas...)
}
}

@ -0,0 +1,107 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_observed.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const (
MetaObservedObserverName = "observed_by"
MetaObservedInstanceName = "observed_instance"
)
type withObserved struct {
error
observer string
instance string
}
func AddObserved(observer string, instance ...string) Adder {
return AddFnc(func(err error) error { return WithObserved(err, observer, instance...) })
}
func WithObserved(err error, observer string, instance ...string) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
var inst string
if len(instance) > 0 {
inst = instance[0]
}
return withObserved{
error: err,
observer: observer,
instance: inst,
}
}
// Observer returns the name of the component or service that observed the error.
func (w withObserved) Observer() string { return w.observer }
// Instance returns the optional instance identifier of the observer.
func (w withObserved) Instance() string { return w.instance }
// Unwrap implements Go 1.13+'s errors.Unwrap interface.
// It returns the wrapped error.
func (w withObserved) Unwrap() error { return w.error }
func (w withObserved) Collect(collector Collector) {
if collector.Options().HasMetas() {
if collector.Options().HasEmpty() {
collector.AddMetas(
MakeMeta(MetaObservedObserverName, w.observer),
MakeMeta(MetaObservedInstanceName, w.instance))
return
}
if len(w.observer) > 0 {
collector.AddMetas(MakeMeta(MetaObservedObserverName, w.observer))
if len(w.instance) > 0 {
collector.AddMetas(MakeMeta(MetaObservedInstanceName, w.instance))
}
}
}
}

@ -0,0 +1,119 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_origin.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const (
MetaOriginClusterName = "origin_cluster"
MetaOriginServerName = "origin_server"
MetaOriginServiceName = "origin_service"
MetaOriginInstanceName = "origin_instance"
)
type withOrigin struct {
error
cluster,
server,
service,
instance string
}
func AddOrigin(cluster, server, service, instance string) Adder {
return AddFnc(func(e error) error { return WithOrigin(e, cluster, server, service, instance) })
}
func WithOrigin(err error, cluster, server, service, instance string) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
return withOrigin{
error: err,
cluster: cluster,
server: server,
service: service,
instance: instance,
}
}
func (w withOrigin) Cluster() string { return w.cluster }
// Service returns the name of the service where the error originated.
func (w withOrigin) Service() string { return w.service }
// Instance returns the optional instance identifier of the originating service.
func (w withOrigin) Instance() string { return w.instance }
// Unwrap implements Go 1.13+'s errors.Unwrap interface.
// It returns the wrapped error.
func (w withOrigin) Unwrap() error { return w.error }
func (w withOrigin) Collect(collector Collector) {
if collector.Options().HasMetas() {
if collector.Options().HasEmpty() {
collector.AddMetas(
MakeMeta(MetaOriginClusterName, w.cluster),
MakeMeta(MetaOriginServerName, w.server),
MakeMeta(MetaOriginServiceName, w.service),
MakeMeta(MetaOriginInstanceName, w.instance))
return
}
if len(w.cluster) > 0 {
collector.AddMetas(MakeMeta(MetaOriginClusterName, w.cluster))
}
if len(w.server) > 0 {
collector.AddMetas(MakeMeta(MetaOriginServerName, w.server))
}
if len(w.service) > 0 {
collector.AddMetas(MakeMeta(MetaOriginServiceName, w.service))
}
if len(w.instance) > 0 {
collector.AddMetas(MakeMeta(MetaOriginInstanceName, w.instance))
}
}
}

@ -0,0 +1,138 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_retryability.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import (
"time"
)
const (
MetaRetryEnabledName = "retry_enabled"
MetaRetryTemporaryName = "retry_temporary"
MetaRetryIdempotentName = "retry_idempotent"
MetaRetryAfterName = "retry_after"
)
const (
// RetryEnabled is a flag indicating the error is potentially retryable.
RetryEnabled uint8 = 1 << iota
// RetryIsTemporary is a flag indicating the error is temporary and might resolve on retry.
RetryIsTemporary
// RetryRetryAfterIsSet is a flag indicating that the 'After' duration is set and should be used for retry delay.
RetryRetryAfterIsSet
// RetryIsIdempotent is a flag indicating that retrying the operation is idempotent (safe to repeat).
RetryIsIdempotent
)
type (
// withRetry is a type that wraps an error and adds information about its retryability.
// This is useful for implementing retry logic in clients or middleware.
withRetry struct {
error // The wrapped error
flags uint8 // A bitmask of Retry flags
after time.Duration // The suggested duration to wait before retrying (only valid if RetryRetryAfterIsSet is set in flags)
}
)
// AddRetry creates a Adder that adds retryable information to an error.
// Takes a bitmask of flags and an optional retry-after duration.
func AddRetry(ops uint8, after time.Duration) Adder {
return AddFnc(func(e error) error {
return WithRetry(e, ops, after)
})
}
// WithRetry creates a new withRetry by wrapping an existing error
// and associating it with retryable flags and an optional retry-after duration.
// Panics if the provided error is nil.
func WithRetry(err error, ops uint8, retryAfter time.Duration) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
return withRetry{
error: err,
flags: ops,
after: retryAfter,
}
}
// CanRetry returns true if the RetryEnabled flag is set.
func (w withRetry) CanRetry() bool { return w.flags&RetryEnabled != 0 }
// IsTemporary returns true if the RetryIsTemporary flag is set.
func (w withRetry) IsTemporary() bool { return w.flags&RetryIsTemporary != 0 }
// IsIdempotent returns true if the RetryIsIdempotent flag is set.
func (w withRetry) IsIdempotent() bool { return w.flags&RetryIsIdempotent != 0 }
// After returns the retry-after duration and a boolean indicating if it was explicitly set.
func (w withRetry) After() time.Duration {
if w.flags&RetryRetryAfterIsSet != 0 {
return w.after
}
return -1
}
// Unwrap implements Go 1.13+'s errors.Unwrap interface.
// It returns the wrapped error.
func (w withRetry) Unwrap() error { return w.error }
func (w withRetry) Collect(collector Collector) {
if collector.Options().HasMetas() {
collector.AddMetas(
MakeMeta(MetaRetryEnabledName, w.CanRetry()),
MakeMeta(MetaRetryTemporaryName, w.IsTemporary()),
MakeMeta(MetaRetryIdempotentName, w.IsIdempotent()))
if dur := w.After(); dur != -1 {
collector.AddMetas(MakeMeta(MetaRetryAfterName, dur))
}
return
}
}

@ -0,0 +1,88 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_severity.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
import "fmt"
const MetaSeverityName = "severity"
type withSeverity struct {
error
severity Severity
}
func AddSeverity(severity Severity) Adder {
return AddFnc(func(err error) error { return WithSeverity(err, severity) })
}
func WithSeverity(err error, severity Severity) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
return withSeverity{
error: err,
severity: severity,
}
}
func (w withSeverity) Severity() Severity { return w.severity }
// Meta interface implementación
func (w withSeverity) Name() string { return MetaSeverityName }
func (w withSeverity) Value() any { return w.severity }
func (w withSeverity) Unwrap() error { return w.error }
func (w withSeverity) Collect(collector Collector) {
fmt.Printf("%v\n", collector.Options())
if collector.Options().HasMetas() {
collector.AddMetas(w)
}
}

@ -0,0 +1,96 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_stack.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const MetaStackName = "stack"
type withStack struct {
error
stack Stack
}
func AddStack(values ...int) Adder {
return AddFnc(func(err error) error { return WithStack(err, values...) })
}
func WithStack(err error, values ...int) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
// Determine offset and max frames from optional values.
ox, mx := 0, -1
if len(values) > 0 {
ox = values[0]
if len(values) > 1 {
mx = values[1]
}
}
return withStack{
error: err,
stack: CreateStack(ox, mx), // Capture the stack trace.
}
}
func (w withStack) Stack() Stack { return w.stack }
func (w withStack) Unwrap() error {
return w.error
}
// Meta interface implementación
func (w withStack) Name() string { return MetaStackName }
func (w withStack) Value() any { return w.stack }
func (w withStack) Collect(collector Collector) {
if collector.Options().HasStack() {
collector.AddStack(w.stack)
}
}

@ -0,0 +1,84 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_status.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const MetaStatusName = "status" // Cambiado para no colisionar con "severity"
type withStatus struct {
error
status int
}
func AddStatus(status int) Adder {
return AddFnc(func(err error) error { return WithStatus(err, status) })
}
func WithStatus(err error, status int) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
return withStatus{
error: err,
status: status,
}
}
// Status devuelve el código de estado numérico asociado.
func (w withStatus) Status() int { return w.status }
// Meta interface implementación
func (w withStatus) Name() string { return MetaStatusName }
func (w withStatus) Value() any { return w.status }
func (w withStatus) Collect(collector Collector) {
if collector.Options().HasMetas() {
collector.AddMetas(w)
}
}

@ -0,0 +1,88 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto FWS
—————————————————————————————————————————————————————————————————————————————
Fichero with_user.go
Package errs
Autor Juan V. Navarro juanvnl@activething.com
Creado 16/01/2026
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/ATGO/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other severity, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | activething.com/FWS
git : g.activething.com | github.com/activething/FWS
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2026 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package errs
const MetaUserName = "user"
type withUser struct {
error
user string
}
func AddUser(user string) Adder {
return AddFnc(func(err error) error { return WithUser(err, user) })
}
func WithUser(err error, user string) error {
if err == nil {
panic(MakePanicError(ErrNilError))
}
return withUser{
error: err,
user: user,
}
}
func (w withUser) Unwrap() error {
return w.error
}
func (w withUser) User() string { return w.user }
// Meta interface implementación
func (w withUser) Name() string { return MetaUserName }
func (w withUser) Value() any { return w.user }
func (w withUser) Collect(collector Collector) {
if collector.Options().HasMetas() {
collector.AddMetas(w)
}
}

@ -0,0 +1,3 @@
module src
go 1.25

@ -0,0 +1,9 @@
go 1.25
use (
./core/errs
./apps/apperrs
)
Loading…
Cancel
Save

Powered by TurnKey Linux.