errs

Áttekintés

Strukturált Go hibák stackkel, kóddal és kliensbiztos üzenettel.

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 Public attribú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étegFelelősség
errsfelépíti és wrappeli a hibát: stack, kód, publikus üzenet, státusz
httperrRFC 9457 problem+json HTTP-válasszá rendereli
a saját kódodbá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:

main.go
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 httperr nélkül.
  • httperr: Áttekintés: a modul, ami az errs hibákat HTTP-re rendereli.
  • Hibamodell: a teljes pipeline, végigvezetve, egy kidolgozott példával.
Copyright © 2026