Skip to content

go1.13 errors package #34060

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

Closed
divinerapier opened this issue Sep 4, 2019 · 2 comments
Closed

go1.13 errors package #34060

divinerapier opened this issue Sep 4, 2019 · 2 comments

Comments

@divinerapier
Copy link

What version of Go are you using (go version)?

$ go version                    
go version go1.13 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/myuser/Library/Caches/go-build"
GOENV="/Users/myuser/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH=""
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/cn/1_54kmt57s135ygwjyg64p_00000gn/T/go-build709008938=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

package main

import (
	"errors"
	"fmt"
)

type Error struct {
	Code    int
	Message string
}

func NewError(code int, message string) *Error {
	return &Error{
		Code:    code,
		Message: message,
	}
}

func (e *Error) Error() string {
	return fmt.Sprintf("code: %d, message: %s", e.Code, e.Message)
}

func main() {
	testVW()
	testWrapErrors()
}

func foo() error {
	return NewError(32, "make an error")
}

func bar() error {
	return NewError(83, "make another error")
}

func testVW() {
	fmt.Println("format with %w")
	err1 := foo()
	err2 := bar()
	err3 := fmt.Errorf("err1: (%w), err2: (%w)", err1, err2)
	err4 := fmt.Errorf("err1: (%v), err2: (%v)", err1, err2)
	fmt.Printf("format with %%v: %v\n", err3)
	fmt.Printf("format with %%w: %v\n", err4)
	fmt.Println()
}

func testWrapErrors() {
	fmt.Println("wrap errors")
	err1 := foo()
	err2 := bar()
	err3 := fmt.Errorf("err1: (%w), err2: (%w)", err1, err2)
	fmt.Printf("%v\n", errors.Unwrap(err3))
}

https://play.golang.org/p/NLhAo_KxfFO

What did you expect to see?

  1. format with %w should same as %v
  2. unwrap some errors

What did you see instead?

format with %w
format with %v: err1: (code: 32, message: make an error), err2: (%!w(*main.Error=&{83 make another error}))
format with %w: err1: (code: 32, message: make an error), err2: (code: 83, message: make another error)

wrap errors
<nil>
@ainar-g
Copy link
Contributor

ainar-g commented Sep 4, 2019

The fmt docs say:

If the format specifier includes a %w verb with an error operand, the returned error will implement an Unwrap method returning the operand. It is invalid to include more than one %w verb or to supply it with an operand that does not implement the error interface. The %w verb is otherwise a synonym for %v.

(Emphasis added.)

@divinerapier
Copy link
Author

thanks @ainar-g

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

No branches or pull requests

3 participants