tag v0.155.0 Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com> Changes with 0.155.0 ---------------- * Fedora 43: add shadow-utils when LockRoot is enabled, update cloud-init service name (osbuild/images#1618) * Author: Achilleas Koutsou, Reviewers: Gianluca Zuccarelli, Michael Vogt * Update osbuild dependency commit ID to latest (osbuild/images#1609) * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger, Tomáš Hozza * Update snapshots to 20250626 (osbuild/images#1623) * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger * distro/rhel9: xz compress azure-cvm image type [HMS-8587] (osbuild/images#1620) * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza * distro/rhel: introduce new image type: Azure SAP Apps [HMS-8738] (osbuild/images#1612) * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza * distro/rhel: move ansible-core to sap_extras_pkgset (osbuild/images#1624) * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Tomáš Hozza * github/create-tag: allow passing the version when run manually (osbuild/images#1621) * Author: Achilleas Koutsou, Reviewers: Lukáš Zapletal, Tomáš Hozza * rhel9: move image-config into pure YAML (HMS-8593) (osbuild/images#1616) * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger * test: split manifest checksums into separate files (osbuild/images#1625) * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza — Somewhere on the Internet, 2025-06-30 --- tag v0.156.0 Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com> Changes with 0.156.0 ---------------- * Many: delete repositories for EOL distributions (HMS-7044) (osbuild/images#1607) * Author: Tomáš Hozza, Reviewers: Michael Vogt, Simon de Vlieger * RHSM/facts: add 'image-builder CLI' API type (osbuild/images#1640) * Author: Tomáš Hozza, Reviewers: Brian C. Lane, Simon de Vlieger * Update dependencies 2025-06-29 (osbuild/images#1628) * Author: SchutzBot, Reviewers: Simon de Vlieger, Tomáš Hozza * Update osbuild dependency commit ID to latest (osbuild/images#1627) * Author: SchutzBot, Reviewers: Simon de Vlieger, Tomáš Hozza * [RFC] image: drop `InstallWeakDeps` from image.DiskImage (osbuild/images#1642) * Author: Michael Vogt, Reviewers: Brian C. Lane, Simon de Vlieger, Tomáš Hozza * build(deps): bump the go-deps group across 1 directory with 3 updates (osbuild/images#1632) * Author: dependabot[bot], Reviewers: SchutzBot, Tomáš Hozza * distro/rhel10: xz compress azure-cvm image type (osbuild/images#1638) * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Simon de Vlieger * distro: cleanup/refactor distro/{defs,generic} (HMS-8744) (osbuild/images#1570) * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza * distro: remove some hardcoded values from generic/images.go (osbuild/images#1636) * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza * distro: small tweaks for the YAML based imagetypes (osbuild/images#1622) * Author: Michael Vogt, Reviewers: Brian C. Lane, Simon de Vlieger * fedora/wsl: packages and locale (osbuild/images#1635) * Author: Simon de Vlieger, Reviewers: Michael Vogt, Tomáš Hozza * image/many: make compression more generic (osbuild/images#1634) * Author: Simon de Vlieger, Reviewers: Brian C. Lane, Michael Vogt * manifest: handle content template name with spaces (osbuild/images#1641) * Author: Bryttanie, Reviewers: Brian C. Lane, Michael Vogt, Tomáš Hozza * many: implement gzip (osbuild/images#1633) * Author: Simon de Vlieger, Reviewers: Michael Vogt, Tomáš Hozza * rhel/azure: set GRUB_TERMINAL based on architecture [RHEL-91383] (osbuild/images#1626) * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza — Somewhere on the Internet, 2025-07-07 ---
235 lines
5.7 KiB
Markdown
235 lines
5.7 KiB
Markdown
# errs
|
|
|
|
[](https://godoc.org/github.com/zeebo/errs)
|
|
[](https://sourcegraph.com/github.com/zeebo/errs?badge)
|
|
[](https://goreportcard.com/report/github.com/zeebo/errs)
|
|
|
|
errs is a package for making errors friendly and easy.
|
|
|
|
### Creating Errors
|
|
|
|
The easiest way to use it, is to use the package level [New][New] function.
|
|
It's much like `fmt.Errorf`, but better. For example:
|
|
|
|
```go
|
|
func checkThing() error {
|
|
return errs.New("what's up with %q?", "zeebo")
|
|
}
|
|
```
|
|
|
|
Why is it better? Errors come with a stack trace that is only printed
|
|
when a `"+"` character is used in the format string. This should retain the
|
|
benefits of being able to diagnose where and why errors happen, without all of
|
|
the noise of printing a stack trace in every situation. For example:
|
|
|
|
```go
|
|
func doSomeRealWork() {
|
|
err := checkThing()
|
|
if err != nil {
|
|
fmt.Printf("%+v\n", err) // contains stack trace if it's a errs error.
|
|
fmt.Printf("%v\n", err) // does not contain a stack trace
|
|
return
|
|
}
|
|
}
|
|
```
|
|
|
|
### Error Classes
|
|
|
|
You can create a [Class][Class] of errors and check if any error was created by
|
|
that class. The class name is prefixed to all of the errors it creates. For example:
|
|
|
|
```go
|
|
var Unauthorized = errs.Class("unauthorized")
|
|
|
|
func checkUser(username, password string) error {
|
|
if username != "zeebo" {
|
|
return Unauthorized.New("who is %q?", username)
|
|
}
|
|
if password != "hunter2" {
|
|
return Unauthorized.New("that's not a good password, jerkmo!")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func handleRequest() {
|
|
if err := checkUser("zeebo", "hunter3"); Unauthorized.Has(err) {
|
|
fmt.Println(err)
|
|
}
|
|
|
|
// output:
|
|
// unauthorized: that's not a good password, jerkmo!
|
|
}
|
|
```
|
|
|
|
Classes can also [Wrap][ClassWrap] other errors, and errors may be wrapped
|
|
multiple times. For example:
|
|
|
|
```go
|
|
var (
|
|
Error = errs.Class("mypackage")
|
|
Unauthorized = errs.Class("unauthorized")
|
|
)
|
|
|
|
func deep3() error {
|
|
return fmt.Errorf("ouch")
|
|
}
|
|
|
|
func deep2() error {
|
|
return Unauthorized.Wrap(deep3())
|
|
}
|
|
|
|
func deep1() error {
|
|
return Error.Wrap(deep2())
|
|
}
|
|
|
|
func deep() {
|
|
fmt.Println(deep1())
|
|
|
|
// output:
|
|
// mypackage: unauthorized: ouch
|
|
}
|
|
```
|
|
|
|
In the above example, both `Error.Has(deep1())` and `Unauthorized.Has(deep1())`
|
|
would return `true`, and the stack trace would only be recorded once at the
|
|
`deep2` call.
|
|
|
|
In addition, when an error has been wrapped, wrapping it again with the same class will
|
|
not do anything. For example:
|
|
|
|
```go
|
|
func doubleWrap() {
|
|
fmt.Println(Error.Wrap(Error.New("foo")))
|
|
|
|
// output:
|
|
// mypackage: foo
|
|
}
|
|
```
|
|
|
|
This is to make it an easier decision if you should wrap or not (you should).
|
|
|
|
### Utilities
|
|
|
|
[Classes][Classes] is a helper function to get a slice of classes that an error
|
|
has. The latest wrap is first in the slice. For example:
|
|
|
|
```go
|
|
func getClasses() {
|
|
classes := errs.Classes(deep1())
|
|
fmt.Println(classes[0] == &Error)
|
|
fmt.Println(classes[1] == &Unauthorized)
|
|
|
|
// output:
|
|
// true
|
|
// true
|
|
}
|
|
```
|
|
|
|
Finally, a helper function, [Unwrap][Unwrap] is provided to get the
|
|
wrapped error in cases where you might want to inspect details. For
|
|
example:
|
|
|
|
```go
|
|
var Error = errs.Class("mypackage")
|
|
|
|
func getHandle() (*os.File, error) {
|
|
fh, err := os.Open("neat_things")
|
|
if err != nil {
|
|
return nil, Error.Wrap(err)
|
|
}
|
|
return fh, nil
|
|
}
|
|
|
|
func checkForNeatThings() {
|
|
fh, err := getHandle()
|
|
if os.IsNotExist(errs.Unwrap(err)) {
|
|
panic("no neat things?!")
|
|
}
|
|
if err != nil {
|
|
panic("phew, at least there are neat things, even if i can't see them")
|
|
}
|
|
fh.Close()
|
|
}
|
|
```
|
|
|
|
It knows about both the `Unwrap() error` and `Unwrap() []error` methods that are
|
|
often used in the community, and will call them as many times as possible.
|
|
|
|
### Defer
|
|
|
|
The package also provides [WrapP][WrapP] versions of [Wrap][Wrap] that are useful
|
|
in defer contexts. For example:
|
|
|
|
```go
|
|
func checkDefer() (err error) {
|
|
defer Error.WrapP(&err)
|
|
|
|
fh, err := os.Open("secret_stash")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return fh.Close()
|
|
}
|
|
```
|
|
|
|
### Groups
|
|
|
|
[Groups][Group] allow one to collect a set of errors. For example:
|
|
|
|
```go
|
|
func tonsOfErrors() error {
|
|
var group errs.Group
|
|
for _, work := range someWork {
|
|
group.Add(maybeErrors(work))
|
|
}
|
|
return group.Err()
|
|
}
|
|
```
|
|
|
|
Some things to note:
|
|
|
|
- The [Add][GroupAdd] method only adds to the group if the passed in error is non-nil.
|
|
- The [Err][GroupErr] method returns an error only if non-nil errors have been added, and
|
|
additionally returns just the error if only one error was added. Thus, we always
|
|
have that if you only call `group.Add(err)`, then `group.Err() == err`.
|
|
|
|
The returned error will format itself similarly:
|
|
|
|
```go
|
|
func groupFormat() {
|
|
var group errs.Group
|
|
group.Add(errs.New("first"))
|
|
group.Add(errs.New("second"))
|
|
err := group.Err()
|
|
|
|
fmt.Printf("%v\n", err)
|
|
fmt.Println()
|
|
fmt.Printf("%+v\n", err)
|
|
|
|
// output:
|
|
// first; second
|
|
//
|
|
// group:
|
|
// --- first
|
|
// ... stack trace
|
|
// --- second
|
|
// ... stack trace
|
|
}
|
|
```
|
|
|
|
### Contributing
|
|
|
|
errs is released under an MIT License. If you want to contribute, be sure to
|
|
add yourself to the list in AUTHORS.
|
|
|
|
[New]: https://godoc.org/github.com/zeebo/errs#New
|
|
[Wrap]: https://godoc.org/github.com/zeebo/errs#Wrap
|
|
[WrapP]: https://godoc.org/github.com/zeebo/errs#WrapP
|
|
[Class]: https://godoc.org/github.com/zeebo/errs#Class
|
|
[ClassNew]: https://godoc.org/github.com/zeebo/errs#Class.New
|
|
[ClassWrap]: https://godoc.org/github.com/zeebo/errs#Class.Wrap
|
|
[Unwrap]: https://godoc.org/github.com/zeebo/errs#Unwrap
|
|
[Classes]: https://godoc.org/github.com/zeebo/errs#Classes
|
|
[Group]: https://godoc.org/github.com/zeebo/errs#Group
|
|
[GroupAdd]: https://godoc.org/github.com/zeebo/errs#Group.Add
|
|
[GroupErr]: https://godoc.org/github.com/zeebo/errs#Group.Err
|