cockroachdb / errors

Go error library with error portability over the network
Apache License 2.0
2.09k stars 67 forks source link

Invalid message of nested error #109

Closed maranqz closed 1 year ago

maranqz commented 1 year ago

Hello. Thank you for the Library and error handling RFC.

I have error ErrDB and the child of that ErrDBNotFound. Then I enrich Err with stack and want to get message "db: not found", but I get "db". I found that extractPrefix cut the part of message, could you give advice how to fix it and why extractPrefix was added?

https://go.dev/play/p/gqT2QOTMcRn

package main

import (
    "errors"
    "fmt"

    crerr "github.com/cockroachdb/errors"
)

var (
    ErrDB         = errors.New("db")
    ErrDBNotFound = fmt.Errorf("%w: not found", ErrDB)
)

func main() {
    err := ErrDBNotFound

    fmt.Println(errors.Is(ErrDBNotFound, ErrDB))
    fmt.Println(err.Error())

    errStl := crerr.WithStack(err)
    fmt.Println(errStl)

    // Output: true
    // db: not found
    // db

    // Want Output:
    // true
    // db: not found
    // db: not found
}

Solution, which I see, but I hope there is more elegant solution and explanation.

  1. fmt.Errorf("%w: %w", ErrDB, ErrDBNotFound)
  2. WithMessage or custom Err with changing func Error() string
knz commented 1 year ago

Try this:

        ErrDBNotFound = fmt.Errorf("object not found: %w", ErrDB)

Alternatively, you can indeed add a custom error object:

type notFound struct {
  error
}

// This is important.
func (e *notFound) FormatError(p errors.Printer) error {
  p.Printf("%s: not found", e.error.Error()) 
  return nil
}

func (e *notFound) Unwrap() error { return e.error }
func (e *notFound) Error() string { return fmt.Sprint(errors.Formattable(e)) }

var        ErrDBNotFound = &notFound{ErrDB}
maranqz commented 1 year ago

Thank you, but I want db: not found to show that not found is error of db like math/big: some error or sql: some error in built in libraries.

Why extractPrefix was added?

knz commented 1 year ago

Thank you, but I want db: not found

Then you can build a custom type as suggested above.

Why extractPrefix was added?

To enable: