Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] No way to check the cause if using a mix of go-errors and standard errors #12

Open
erizocosmico opened this issue Aug 2, 2019 · 7 comments

Comments

@erizocosmico
Copy link
Contributor

erizocosmico commented Aug 2, 2019

Let's imagine we are using a mix of this library and standard errors created with errors.New or fmt.Errorf.

Consider the following snippet:

var errStd = stderrors.New("something")

var errKind = errors.NewKind("something: %s")

var myErr = errKind.Wrap(errStd, "foo")

If we want to check if myErr has errStd as its cause, we need to do the following:

 err, ok := myErr.(*errors.Error)
if !ok {
  // handle
}
if err.Cause() == errStd {
}

This is potentially more cumbersome if the original error is deeply nested.
Perhaps we could have a function IsCausedBy(err, cause).

In this case, it would become:

if errors.Is(myErr, errStd) {
  // do something
}

Implementation could look like this:

func Is(err, cause error) bool {
    e, ok := err.(*Error)
    if !ok {
        return false
    }
    
    if e, ok := e.cause.(*Error); ok {
        return Is(e, cause)
    }

    return e.cause == cause
}
@erizocosmico erizocosmico changed the title No way to check the cause if using a mix of go-errors and standard errors [Proposal] No way to check the cause if using a mix of go-errors and standard errors Aug 2, 2019
@creachadair
Copy link

This looks very similar to the semantics of the current error inspection proposal implemented by https://godoc.org/golang.org/x/xerrors.

@erizocosmico
Copy link
Contributor Author

erizocosmico commented Aug 2, 2019 via email

@creachadair
Copy link

creachadair commented Aug 2, 2019

Yup, this and the other proposal are basically bringing the good bits of xerrors to go-errors so the library it’s more stderror friendly

That makes sense. But I wonder if it's possible to do so by integrating with the Wrapper API so that (say) xerrors.Is and xerrors.As would work without needing a new helper?

@erizocosmico
Copy link
Contributor Author

Yeah, implementing Wrapper would be nice as well, but for a go-errors user, the point of using the library is not needing to use errors (xerrors in this case), so that all you need to handle errors is in there. If we were to only implement Wrapper you'd need to also import xerrors (or errors when it's merged into the stdlib) for that specific use case.
We can have the implementation of Wrapper to make go-errors errors usable with xerrors, but I'd still suggest adding a helper here.

@creachadair
Copy link

We can have the implementation of Wrapper to make go-errors errors usable with xerrors, but I'd still suggest adding a helper here.

That makes sense. You might consider using the same name, though, so that errors.Is maps to the semantics of xerrors.Is.

@creachadair
Copy link

By the way, the standard library already has an errors package, that most non-trivial Go programs already use (it's the origin of errors.New for example). At source{d} we mostly do not use the stdlib errors directly, but it's very common in most Go codebases. So if/when the xerrors proposal gets integrated, it shouldn't add any build mass to the packages that use it. (That doesn't affect this package directly, though)

@erizocosmico
Copy link
Contributor Author

That makes sense. You might consider using the same name, though, so that errors.Is maps to the semantics of xerrors.Is.

Fair enough.

So if/when the xerrors proposal gets integrated, it shouldn't add any build mass to the packages that use it.

It wasn't because of adding size to the binary. It was because when using go-errors, one should not need to use any other library for error handling, since all needed features are expected to be provided by the library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants