Errors and Panics
Ignore Errors
Many functions return an error as their second argument, and you may know that the error won’t be encountered for some reason. In that case, ignoring the error is nice, but the first return type might vary, so use a generic to ignore errors like this:
package main
import (
"fmt"
"strconv"
)
func IgnoreError[T any](out T, _ error) T {
return out
}
func main() {
i0 := IgnoreError(strconv.Atoi("3"))
i1 := IgnoreError(strconv.Atoi("M"))
b0 := IgnoreError(strconv.ParseBool("true"))
b1 := IgnoreError(strconv.ParseBool("banana"))
fmt.Printf("i0=%d, i1=%d, b0=%t, b1=%t\n", i0, i1, b0, b1)
_, e0 := strconv.Atoi("M")
fmt.Println(e0.Error())
_, e1 := strconv.ParseBool("banana")
fmt.Println(e1.Error())
}
import (
"fmt"
"strconv"
)
func IgnoreError[T any](out T, _ error) T {
return out
}
func main() {
i0 := IgnoreError(strconv.Atoi("3"))
i1 := IgnoreError(strconv.Atoi("M"))
b0 := IgnoreError(strconv.ParseBool("true"))
b1 := IgnoreError(strconv.ParseBool("banana"))
fmt.Printf("i0=%d, i1=%d, b0=%t, b1=%t\n", i0, i1, b0, b1)
_, e0 := strconv.Atoi("M")
fmt.Println(e0.Error())
_, e1 := strconv.ParseBool("banana")
fmt.Println(e1.Error())
}
When run, the above code prints:
i0=3, i1=0, b0=true, b1=false
strconv.Atoi: parsing "M": invalid syntax
strconv.ParseBool: parsing "banana": invalid syntax
Panic! Or Don’t
The following example shows how to do all of the following:
- promote errors to panics
- ignore panics
- reduce panics to errors
package main
import (
"fmt"
"strconv"
)
// PanicOnError returns the first input, or panics if the second argument is
// a non-nil error.
func PanicOnError[T any](out T, err error) T {
if err != nil {
panic(err)
}
return out
}
// IgnorePanic runs the function given, and ignores any panic thrown.
func IgnorePanic(whinyFunction func()) {
defer func() { recover() }()
whinyFunction()
}
func ErrorOnPanic(whinyFunction func()) (err error) {
defer func() {
p := recover()
if p != nil {
err = fmt.Errorf("%v", p)
}
}()
whinyFunction()
return
}
func main() {
var x, y int
IgnorePanic(func() {
x = PanicOnError(strconv.Atoi("3"))
y = PanicOnError(strconv.Atoi("M"))
})
fmt.Printf("x=%d, y=%d\n", x, y)
e0 := ErrorOnPanic(func() {
PanicOnError(strconv.Atoi("M"))
})
fmt.Printf(e0.Error())
}
import (
"fmt"
"strconv"
)
// PanicOnError returns the first input, or panics if the second argument is
// a non-nil error.
func PanicOnError[T any](out T, err error) T {
if err != nil {
panic(err)
}
return out
}
// IgnorePanic runs the function given, and ignores any panic thrown.
func IgnorePanic(whinyFunction func()) {
defer func() { recover() }()
whinyFunction()
}
func ErrorOnPanic(whinyFunction func()) (err error) {
defer func() {
p := recover()
if p != nil {
err = fmt.Errorf("%v", p)
}
}()
whinyFunction()
return
}
func main() {
var x, y int
IgnorePanic(func() {
x = PanicOnError(strconv.Atoi("3"))
y = PanicOnError(strconv.Atoi("M"))
})
fmt.Printf("x=%d, y=%d\n", x, y)
e0 := ErrorOnPanic(func() {
PanicOnError(strconv.Atoi("M"))
})
fmt.Printf(e0.Error())
}
When the above code runs, it prints:
x=3, y=0
strconv.Atoi: parsing "M": invalid syntax