更新到 Go 1.15 或更高版本后出现错误 “panic: 无法从空父上下文创建上下文”。

huangapple go评论98阅读模式
英文:

Error "panic: cannot create context from nil parent" after updating to Go 1.15 or higher

问题

在更新到Go 1.15之后,运行我的代码(一个单元测试)时出现了以下错误:

panic: 无法从空父上下文创建上下文

goroutine 14 [running]:
testing.tRunner.func1.2(0x1211480, 0x12a3dc8) /usr/local/opt/go/libexec/src/testing/testing.go:1143
+0x332 testing.tRunner.func1(0xc000178900) /usr/local/opt/go/libexec/src/testing/testing.go:1146 +0x4b6
panic(0x1211480, 0x12a3dc8)
/usr/local/opt/go/libexec/src/runtime/panic.go:965 +0x1b9
context.WithValue(0x0, 0x0, 0x1210940, 0x12a3f58, 0x1241b80,
0xc00007c910, 0x12a3f58, 0xc00004a770)
/usr/local/opt/go/libexec/src/context/context.go:521 +0x187
/usr/local/opt/go/libexec/src/context/context.go:521 +0x187
github.com/myrepo/pkg/test.Test_failure(0xc000765200)
/pkg/test.go:43 +0x15f

这是我的代码:

ctx := context.WithValue(nil, "some string", nil)
req := http.Request{}
req = *req.WithContext(ctx)
英文:

After updating to Go 1.15 I'm getting this error when running my code (a unit test):

> panic: cannot create context from nil parent
>
> goroutine 14 [running]:
> testing.tRunner.func1.2(0x1211480, 0x12a3dc8) /usr/local/opt/go/libexec/src/testing/testing.go:1143
> +0x332 testing.tRunner.func1(0xc000178900) /usr/local/opt/go/libexec/src/testing/testing.go:1146 +0x4b6
> panic(0x1211480, 0x12a3dc8)
> /usr/local/opt/go/libexec/src/runtime/panic.go:965 +0x1b9
> context.WithValue(0x0, 0x0, 0x1210940, 0x12a3f58, 0x1241b80,
> 0xc00007c910, 0x12a3f58, 0xc00004a770)
> /usr/local/opt/go/libexec/src/context/context.go:521 +0x187
> /usr/local/opt/go/libexec/src/context/context.go:521 +0x187
> github.com/myrepo/pkg/test.Test_failure(0xc000765200)
> /pkg/test.go:43 +0x15f

This is my code:

ctx := context.WithValue(nil, "some string", nil)
req := http.Request{}
req = *req.WithContext(ctx)

答案1

得分: 2

要翻译的内容如下:

要么使用context.Background(),要么使用context.TODO()作为种子,如果没有上游上下文,则使用前者。

你可以在这里看到文档中说应该使用context.Background()作为初始种子。
https://pkg.go.dev/context#Background

> func Background ¶
func Background() Context
Background返回一个非nil的空Context。它永远不会被取消,没有值,也没有截止日期。它通常由主函数、初始化和测试使用,并作为传入请求的顶级Context。

通常情况下,你不应该在第一次放置nil。

英文:

Either use context.Background() or context.TODO() as seed if you do not have an upstream context, if you have then pass that one.

You can see here that the docs say context.Background() should be used as initial seed.
https://pkg.go.dev/context#Background

> func Background ¶
func Background() Context
Background returns a non-nil, empty Context. It is never canceled, has no values, and has no deadline. It is typically used by the main function, initialization, and tests, and as the top-level Context for incoming requests.

Generally you shouldn't have put nil there in the first place.

答案2

得分: 1

根据Go 1.15文档,不再允许传入空的父上下文:

使用空的父上下文创建派生上下文现在明确是不允许的。尝试使用WithValue、WithDeadline或WithCancel函数进行此操作将导致恐慌。

为了解决这个问题,我最终使用了context.TODO()

ctx := context.WithValue(context.TODO(), "some string", nil)

TODO函数返回一个非空的空上下文。当不确定使用哪个上下文或者上下文尚不可用(因为周围的函数尚未扩展以接受上下文参数)时,代码应该使用context.TODO。

英文:

According to the Go 1.15 documentation passing in a nil parent is not allowed anymore:

> Creating a derived Context using a nil parent is now explicitly
> disallowed. Any attempt to do so with the WithValue, WithDeadline, or
> WithCancel functions will cause a panic.

To fix the issue I ended up using context.TODO():

ctx := context.WithValue(context.TODO(), "some string", nil)

> TODO returns a non-nil, empty Context. Code should use context.TODO
> when it's unclear which Context to use or it is not yet available
> (because the surrounding function has not yet been extended to accept
> a Context parameter).

huangapple
  • 本文由 发表于 2021年8月19日 07:46:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/68840479.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定