mirror of
https://github.com/golang/go
synced 2024-11-22 16:34:47 -07:00
aa51c40b1c
Long ago we decided that panic(nil) was too unlikely to bother making a special case for purposes of recover. Unfortunately, it has turned out not to be a special case. There are many examples of code in the Go ecosystem where an author has written panic(nil) because they want to panic and don't care about the panic value. Using panic(nil) in this case has the unfortunate behavior of making recover behave as though the goroutine isn't panicking. As a result, code like: func f() { defer func() { if err := recover(); err != nil { log.Fatalf("panicked! %v", err) } }() call1() call2() } looks like it guarantees that call2 has been run any time f returns, but that turns out not to be strictly true. If call1 does panic(nil), then f returns "successfully", having recovered the panic, but without calling call2. Instead you have to write something like: func f() { done := false defer func() { if err := recover(); !done { log.Fatalf("panicked! %v", err) } }() call1() call2() done = true } which defeats nearly the whole point of recover. No one does this, with the result that almost all uses of recover are subtly broken. One specific broken use along these lines is in net/http, which recovers from panics in handlers and sends back an HTTP error. Users discovered in the early days of Go that panic(nil) was a convenient way to jump out of a handler up to the serving loop without sending back an HTTP error. This was a bug, not a feature. Go 1.8 added panic(http.ErrAbortHandler) as a better way to access the feature. Any lingering code that uses panic(nil) to abort an HTTP handler without a failure message should be changed to use http.ErrAbortHandler. Programs that need the old, unintended behavior from net/http or other packages can set GODEBUG=panicnil=1 to stop the run-time error. Uses of recover that want to detect panic(nil) in new programs can check for recover returning a value of type *runtime.PanicNilError. Because the new GODEBUG is used inside the runtime, we can't import internal/godebug, so there is some new machinery to cross-connect those in this CL, to allow a mutable GODEBUG setting. That won't be necessary if we add any other mutable GODEBUG settings in the future. The CL also corrects the handling of defaulted GODEBUG values in the runtime, for #56986. Fixes #25448. Change-Id: I2b39c7e83e4f7aa308777dabf2edae54773e03f5 Reviewed-on: https://go-review.googlesource.com/c/go/+/461956 Reviewed-by: Robert Griesemer <gri@google.com> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Russ Cox <rsc@golang.org> |
||
---|---|---|
.. | ||
next | ||
except.txt | ||
go1.1.txt | ||
go1.2.txt | ||
go1.3.txt | ||
go1.4.txt | ||
go1.5.txt | ||
go1.6.txt | ||
go1.7.txt | ||
go1.8.txt | ||
go1.9.txt | ||
go1.10.txt | ||
go1.11.txt | ||
go1.12.txt | ||
go1.13.txt | ||
go1.14.txt | ||
go1.15.txt | ||
go1.16.txt | ||
go1.17.txt | ||
go1.18.txt | ||
go1.19.txt | ||
go1.20.txt | ||
go1.txt | ||
README |
Files in this directory are data for Go's API checker ("go tool api", in src/cmd/api). Each file is a list of API features, one per line. go1.txt (and similarly named files) are frozen once a version has been shipped. Each file adds new lines but does not remove any. except.txt lists features that may disappear without breaking true compatibility. Starting with go1.19.txt, each API feature line must end in "#nnnnn" giving the GitHub issue number of the proposal issue that accepted the new API. This helps with our end-of-cycle audit of new APIs. The same requirement applies to next/* (described below), which will become a go1.XX.txt for XX >= 19. The next/ directory contains the only files intended to be mutated. Each file in that directory contains a list of features that may be added to the next release of Go. The files in this directory only affect the warning output from the go api tool. Each file should be named nnnnn.txt, after the issue number for the accepted proposal. (The #nnnnn suffix must also appear at the end of each line in the file; that will be preserved when next/*.txt is concatenated into go1.XX.txt.)