go/book/learninggo

Sentinel Errors

Don’t just check errors, handle them gracefully | Dave Cheney

sentinel errors are predefined, named errors that are used to represent specific error conditions. They are declared as variables at the package level and are used as constants in the sense that their identity is fixed and should never change.
They are called “sentinels” because they act as a fixed marker in your code, signaling a known situation or condition.

Sentinel errors are usually used to indicate that you cannot start or continue processing. For example, the standard library includes a package for processing ZIP files, archive/zip.

  • Sentinel errors start with Err, e.g., ErrNotFound, ErrPermissionDenied.
  • The exception is io.EOF, which does not follow the Err prefix but is still a sentinel.
// Defining sentinel errors
var ErrNotFound = errors.New("item not found")
var ErrPermissionDenied = errors.New("permission denied")
 
// A function that might return a sentinel error
func findItem(item string) error {
    if item == "" {
        return ErrNotFound
    }
    return nil
}
 
func main() {
    err := findItem("")
    if err != nil {
        if errors.Is(err, ErrNotFound) {
            fmt.Println("Error: Item was not found.")
        } else if errors.Is(err, ErrPermissionDenied) {
            fmt.Println("Error: Permission was denied.")
        } else {
            fmt.Println("An unexpected error occurred:", err)
        }
    } else {
        fmt.Println("Item found successfully.")
    }
}