Skip to content

common/errors: implement Unwrap on *Error for errors.Is/As support#3746

Open
bindreams wants to merge 2 commits into
v2fly:masterfrom
bindreams:errors-unwrap
Open

common/errors: implement Unwrap on *Error for errors.Is/As support#3746
bindreams wants to merge 2 commits into
v2fly:masterfrom
bindreams:errors-unwrap

Conversation

@bindreams

Copy link
Copy Markdown

Add Unwrap() to *Error so errors.Is/As/Unwrap traverse the inner chain. Until now *Error exposed its wrapped error only through Inner()/Cause(), so standard-library unwrapping stopped at the first *Error.

A low-level error wrapped in *Error layers can now be recovered directly:

var errno syscall.Errno
errors.As(listenErr, &errno) // now found through the *Error chain

Strictly additive: Unwrap returns the existing inner field (nil when unset), so it can only surface matches that were previously unreachable, never change one.

@bindreams

Copy link
Copy Markdown
Author

Let me take this moment to thank you for the good work on v2ray! Internet freedom, one commit at a time :)

@xiaokangwang

Copy link
Copy Markdown
Contributor

I think it is okay to add this Unwrap(), but could you please explain what user observable change it makes?

@bindreams

Copy link
Copy Markdown
Author

Hi @xiaokangwang sorry for the late reply.

The only observable change is for the developers inspecting v2ray errors. Unwrap() is a stdlib contract (see https://pkg.go.dev/errors) and it allows me as a consumer of v2ray to inspect the error using standard Go methods errors.Is/errors.As:

conn, err := core.Dial(ctx, instance, dest)
    if err != nil {
        // An error — abort, or retry? Let me cast to Errno and check:
        var errno syscall.Errno
        if errors.As(err, &errno) && (errno == syscall.ECONNREFUSED || errno == syscall.ETIMEDOUT) {
            // back off and retry
        }
        return err // abort
  }

See also the last test from the ones I've added.

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

Successfully merging this pull request may close these issues.

2 participants