pull try
out of Add
deferring a recovery handler is normal in Go but opaque. Pulling out a helper for this (`try`) makes it more obvious that this is just another "if this operation fails, return error" case.
This commit is contained in:
parent
68cab7d2be
commit
a237fa81bf
@ -220,7 +220,7 @@ var ErrFieldSetPanic = fmt.Errorf("%w: panic when setting", ErrBadFieldLabel)
|
|||||||
// Use a FieldLabel to add an amount to the matching field. If no such
|
// Use a FieldLabel to add an amount to the matching field. If no such
|
||||||
// field can be found, the field is not exported, or the field is not
|
// field can be found, the field is not exported, or the field is not
|
||||||
// of type float64, this returns an error ad does not change any values.
|
// of type float64, this returns an error ad does not change any values.
|
||||||
func (k *KoboldMine) Add(which FieldLabel, amount float64) (finalErr error) {
|
func (k *KoboldMine) Add(which FieldLabel, amount float64) error {
|
||||||
kv := reflect.ValueOf(k).Elem()
|
kv := reflect.ValueOf(k).Elem()
|
||||||
f := kv.FieldByName(string(which))
|
f := kv.FieldByName(string(which))
|
||||||
if !f.IsValid() {
|
if !f.IsValid() {
|
||||||
@ -230,15 +230,8 @@ func (k *KoboldMine) Add(which FieldLabel, amount float64) (finalErr error) {
|
|||||||
return fmt.Errorf("cannot add %f to field %q: %w", amount, which, ErrFieldNotFloat)
|
return fmt.Errorf("cannot add %f to field %q: %w", amount, which, ErrFieldNotFloat)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
if err := try(func() { f.SetFloat(f.Float() + amount) }); err != nil {
|
||||||
if r := recover(); r != nil {
|
return fmt.Errorf("could not add %f to field %q: %w", amount, which, err)
|
||||||
if e, ok := r.(error); ok {
|
|
||||||
finalErr = fmt.Errorf("could not add %f to field %q: %w: %w", amount, which, ErrFieldSetPanic, e)
|
|
||||||
} else {
|
|
||||||
finalErr = fmt.Errorf("could not add %f to field %q: %w: %v", amount, which, ErrFieldSetPanic, r)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}()
|
|
||||||
f.SetFloat(f.Float() + amount)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package koboldsim
|
package koboldsim
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"golang.org/x/exp/constraints"
|
"golang.org/x/exp/constraints"
|
||||||
@ -47,3 +49,23 @@ func clamp[T constraints.Ordered](a, b, c T) T {
|
|||||||
// `a` is neither most nor least; therefore, `a` is mid
|
// `a` is neither most nor least; therefore, `a` is mid
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrWrappedPanic = errors.New("panic")
|
||||||
|
|
||||||
|
// try catches a panic in the provided func and demotes it to an error, if any
|
||||||
|
// panic occurs. The returned error, if any, wraps `ErrWrappedPanic`. If the
|
||||||
|
// panic argument is itself an error, it is also wrapped; otherwise, it is
|
||||||
|
// stringified into the error message using `%v`.
|
||||||
|
func try(f func()) (finalErr error) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
if e, ok := r.(error); ok {
|
||||||
|
finalErr = fmt.Errorf("%w: %w", ErrWrappedPanic, e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
finalErr = fmt.Errorf("%w: %v", ErrWrappedPanic, r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
f()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user