【问题标题】:Error "panic: cannot create context from nil parent" after updating to Go 1.15 or higher更新到 Go 1.15 或更高版本后出现错误“panic: cannot create context from nil parent”
【发布时间】:2021-10-20 17:27:31
【问题描述】:

更新到 Go 1.15 后,运行代码(单元测试)时出现此错误:

恐慌:无法从 nil 父级创建上下文

goroutine 14 [运行中]: 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 恐慌(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)

【问题讨论】:

  • 文档总是说“不要传递 nil 上下文,即使函数允许它”
  • 是的,这从来都不是一个好主意。然而,这是可能的,也是允许的。 :)
  • 这真的不仅仅是“不是一个好主意”——它直接违背了文档告诉你的做法。
  • 不幸的是,有无数不正确但可能发生的事情。文档始终是最好的起点。

标签: go


【解决方案1】:

如果您没有上游上下文,则使用 context.Background()context.TODO() 作为种子,如果您有,则通过该上下文。

您可以在此处看到文档说 context.Background() 应该用作初始种子。 https://pkg.go.dev/context#Background

函数背景¶ func Background() 上下文 背景返回一个非零的空上下文。它永远不会被取消,没有价值,也没有最后期限。它通常由主函数、初始化和测试使用,并作为传入请求的顶级上下文。

一般来说,你一开始就不应该把 nil 放在那里。

【讨论】:

  • 谢谢,虽然 TODO() 和 Background() 返回相同的东西,但在测试中使用时最好使用 Background()。
【解决方案2】:

根据Go 1.15 documentation,不再允许传入 nil 父级:

现在显式地使用 nil 父级创建派生上下文 不允许。使用 WithValue、WithDeadline 或 WithCancel 函数会引起恐慌。

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

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

TODO 返回一个非零的空上下文。代码应该使用 context.TODO 当不清楚要使用哪个上下文或尚不可用时 (因为周围的功能还没有被扩展接受 一个上下文参数)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    • 2013-11-12
    • 2020-05-25
    • 2023-02-09
    相关资源
    最近更新 更多