linodego
linodego copied to clipboard
[Feature]: Helper functions for working with errors
Description
While working with the Linode API, I found myself repeating a pattern for checking which specific error was returned from a failed API request.
The pattern is roughly the following:
- Call a method on
linodego.Client; - Unwrap the error to a
*linodego.Errorwitherrors.As; - If the unwrapping is successful, and has an expected error code, handle it.
client := linodego.NewClient(http.DefaultClient)
var lerr *linodego.Error
if err := client.DeleteObjectStorageKey(context.Background(), 12345); errors.As(err, &lerr) && lerr.StatusCode() == http.StatusNotFound {
// Handle the expected error.
} else if err != nil {
// I have an unexpected error, this is usually a simple...
return fmt.Errorf("delete object storage key: %w", err)
}
Performing a simple if err != nil does not work in all situations, since I may want to "successfully fail" past (in this case) the DeleteObjectStorageKey request returning a 404 Not Found response.
Proposal
Addition of two, new functions to the module:
-
ErrHasStatus(err error, codes ...int) bool— useserrors.Asto try and unwraperrto a*linodego.Error, before checking to see iflinodego.Error.StatusCodematches any of the providedcodes. -
IsNotFound(err error) bool— a thin wrapper overErrHasStatusCodes(err, http.StatusNotFound)for checking if theerrorreturned from an API call is a404 Not Found, but providing a convenience for (what in my experience has been) a common use-case. However, if this isn't considered a valuable or useful addition, that's totally okay. :smile:
Example Code
IsNotFound
client := linodego.NewClient(http.DefaultClient)
if err := client.DeleteObjectStorageKey(context.Background(), 12345); linodego.IsNotFound(err) {
// I am expecting this, but I have more stuff to do further down.
} else if err != nil {
// handle the unexpected error accordingly
}
ErrHasStatus
client := linodego.NewClient(http.DefaultClient)
instance, err := client.GetInstance(context.Background(), 123456)
if linodego.ErrHasStatus(err, http.StatusUnauthorized) {
// oops, forgot my wallet at home
} else if linodego.ErrHasStatus(err, http.StatusTooManyRequests) {
// cool my jets
} else if err != nil {
// welp, didn't expect this...
}