Áttekintés
Az errs önálló, csak a standard libraryre épülő Go modul (github.com/gp-system/errs): olyan hibák, amelyek stack trace-t, gépi olvasású kódot és kliensbiztos publikus üzenetet hordoznak, a szokásos becsomagolt belső üzenet mellett. Nulla harmadik féltől származó függősége van, bármilyen Go programban működik (CLI-ben, Lambdában, sima net/http service-ben), és semmilyen más gp-system modulra nincs szüksége ahhoz, hogy hasznos legyen. A gpsystem kit pontosan egy okból használja: ez a hibatípus, amit minden service, repository és handler épít és wrappel egy generált projektben, és ezt a típust rendereli HTTP-re a httperr. Lásd a Hibamodell oldalt, hogy a kettő hogyan illeszkedik egy teljes kérésen keresztül.
Telepítés
go get github.com/gp-system/errs@v0.1.0 # a kit is ezt a taget használja
go get github.com/gp-system/errs@latest
Go 1.25+, és semmi más: az errs kizárólag a standard libraryt importálja (errors, fmt, runtime, log/slog). A projektbe húzása így egyetlen tranzitív függőséget sem hoz be.
Miért két üzenet
Minden hiba, amit az errs épít, két szöveget hordoz, szándékosan szétválasztva:
- a belső üzenet (
Error()): a teljes részlet, neked szól. Tartalmazza a wrap-láncot, így egy hibázó query, egy termékazonosító, egy downstream timeout mind itt jelenik meg. - a publikus üzenet (a
Publicattribútummal állítható be): az egyetlen szöveg, amit a kliens valaha láthat. Ha nincs beállítva, egyszerűen nincs mit kiszivárogtatni; semmi nem esik vissza a belső üzenetre.
A kettő szétválasztása azt jelenti, hogy egy elszabadult, válaszba írt err.Error() sosem szivárogtathat ki belső részletet: bármi is rendereli a hibát (az alábbi minimális mapper, vagy a httperr) az errs.PublicOf-ot olvassa, soha nem az Error()-t. A státuszkód ugyanígy utazik: a hiba definiálásának pontján van beállítva, nem egy handlerbeli if-ágban döntik el utólag. Egy errs hiba ebben az értelemben önmagában is egy kis API-kontraktus: kód, publikus üzenet és státusz együtt írja le egy hibamódot, függetlenül attól, hogy végül mi rendereli.
Mi kell még a rendereléshez
Az errs felépíti és hordozza a hibát. Nem tudja, hogy néz ki egy HTTP-válasz, egy JSON body vagy egy logsor: a renderelés külön felelősség, a fölötte lévő rétegé, ami az errs.CodeOf/PublicOf/StatusOf-ot byte-okká alakítja a dróton.
| Réteg | Felelősség |
|---|---|
errs | felépíti és wrappeli a hibát: stack, kód, publikus üzenet, státusz |
httperr | RFC 9457 problem+json HTTP-válasszá rendereli |
| a saját kódod | bármi más: egy gRPC status, egy CLI exit code, egy queue-üzenet boríték |
Ha nem HTTP-n vagy, vagy nem akarod az extra függőséget, az Integráció oldal mutat egy elég kicsi mappert ahhoz, hogy magad megírd, csak errs-szel, httperr nélkül.
Önálló példa
Sima Go program, HTTP és kit nélkül:
package main
import (
"errors"
"fmt"
"net/http"
"github.com/gp-system/errs"
)
var ErrOutOfStock = errs.Define("out_of_stock",
errs.Public("A termék elfogyott."),
errs.Status(http.StatusConflict))
func decrementStock(productID string, qty int) error {
if qty > 3 {
return ErrOutOfStock.New("decrement stock",
errs.With("product_id", productID))
}
return nil
}
func placeOrder(productID string) error {
if err := decrementStock(productID, 5); err != nil {
if errors.Is(err, ErrOutOfStock) {
return err // várt hiba: megy tovább változatlanul
}
return errs.Wrap(err, "place order")
}
return nil
}
func main() {
err := placeOrder("prod_42")
fmt.Println(err) // belső üzenet, neked
fmt.Println(errs.PublicOf(err)) // "A termék elfogyott.", kliensnek biztonságos
fmt.Println(errs.StatusOf(err)) // 409
fmt.Println(errs.CodeOf(err)) // "out_of_stock"
}
Kapcsolódó oldalak
- errs: API: a teljes
New/Wrap/Define/attribútumok/accessorok végigvezetés. - errs: Integráció: logolás, Sentry, és egy minimális HTTP mapper
httperrnélkül. - httperr: Áttekintés: a modul, ami az
errshibákat HTTP-re rendereli. - Hibamodell: a teljes pipeline, végigvezetve, egy kidolgozott példával.