go
go copied to clipboard
proposal: net/url: add MustParse
I always find it tedious to use httputil.ReverseProxy because you usually need a *url.URL and you can't make one easily without a few lines of boilerplate.
Proposal: add url.MustParse like regexp.MustCompile, template.Must, etc.
(Alternatively: a generic must.Do somewhere in std)
cc @neild
Alternatively: a generic
must.Dosomewhere in std
I'd support this: we already have other similar APIs like https://pkg.go.dev/text/template#Must and https://pkg.go.dev/regexp#MustCompile, and there's really nothing special about them. Some standard support for must could also be nice for one-off scripts or short examples, where panicking on errors is perfectly fine, e.g. https://go-review.googlesource.com/c/go/+/196497.
I realise that some of what I wrote above overlaps with the try proposal, but I think they are distinct, because handling errors by panicking is generally not a good idea in most Go code. I think must would see most of its use in init funcs or global variables, one-off programs, examples, and other similar cases where returning a proper error isn't possible or necessary.
I literally wrote a commit last night and thought, I should propose url.MustParse because I was wrapping so many can't fail package level URLs: https://github.com/spotlightpa/almanack/commit/40fcde98ffa3c9327800e8da68e8750780325d29
We're using this for our codebase: https://pkg.go.dev/tailscale.com/util/must#Get
// Get returns v as is. It panics if err is non-nil.
func Get[T any](v T, err error) T {
if err != nil {
panic(err)
}
return v
}
We've found it surprisingly useful (var target = must.Get(url.Parse(...)), etc)
must.Get and must.Do are better names than try.To and try.Must. I will borrow your names. :-)
I'm not sure if this should be in the standard library or not. We've all written quickie scripts with die(error) or check(error) that panics or calls log.Fatal, so it's definitely a very common practice in real world code, but it's also probably good if there is some friction to doing it because it's not actually a best practice. Then again maybe the standard library could offer it and people could decide for themselves if they want to use it. +0
We've all written quickie scripts with die(error) or check(error) that panics or calls log.Fatal
One question is intent. The tailscale must package is intended to be safe to use in production code where the naming of the package makes it very clear that dying is part of its behavior when errors occur. It's great for initializing global variables.
In sufficiently large Go "scripts", you may want some degree of error handling, where the do-or-die approach of must is no longer a good fit. The github.com/dsnet/try package is intended to be halfway between what must does and the typical approach of error handling in Go.
Some more prior art from the codebase I work on: https://pkg.go.dev/github.com/ridge/must/v2 - must.OK and must.Do