On Tue, Jan 7, 2020 at 8:10 AM Tay <welcometothebasem...@gmail.com> wrote:

> Hi,
>
> Just a quick question. I know it's well accepted that panics leaking to
> the public API of a library is generally a no-go.
>

Not *that* well accepted :) I tend to disagree. But maybe I'm simply in a
vanishingly small minority.

Yet, are there any exception to the rule?
>

The standard library offers a lot of exceptions. The reflect and the
math/big packages, for example, use panics explicitly to alert to bugs.
Going further, the vast majority of methods which uses pointer-receivers
"leaks panics" if called on a nil-pointer, or any function which calls
methods on an interface, if that's nil - which means almost all packages
panic in at least *some* circumstances.

Personally, I consider panics "run-time type-errors". That is, they
indicate a bug that couldn't be caught statically by the type-system - so
the program shouldn't have compiled in the first place and crashing it is
the right choice. Dereferencing a nil-pointer or indexing out-of-bounds
fall into that category. So does using reflect to do otherwise invalid
operations (which is why reflect panics). IMO, a straight-out rejection of
panics doesn't make sense, unless you assume your type-system is perfect
and so there are no bug-free programs.

Another way to look at it, is that a panic in general dumps a stack-trace,
while an error is being presented to the human using the resulting
software. And that stack-traces in general are not actionable to the user
of a software, but only its developer - while error message don't contain
the necessary details to debug a program, but can (should!) provide
actionable advise to its user. Thus, panics are the right tool to use when
reporting an issue that requires programmer attention and errors are the
right tool when reporting an issue that requires user-attention (or, of
course, can be handled programmatically).¹

For instance, I have a library that instantiates some database prepared
> statements (so, the majority of the elements are instantiated and used in
> the main function). I would like to panic instead of returning an error
> because, if db.Prepare(q) returns an error, there is no point in
> continuing, the error is barely recoverable. Besides, it will allow for a
> better looking API so to speak.
>

A prepared statement could fail to compile for reasons that are not bugs,
as AFAIK they are compiled in the database-server. So if that's
unavailable, or there is a version-incompatibility, or some resource is
exhausted… statement-preparation could fail and just indicate a normal
error, just like os.Open or the like. In other words, an error in preparing
a statement could originate outside the program itself.

So, based on my own perspective above, I wouldn't panic in this case. Note
that whether or not that error is recoverable (in your opinion) is
immaterial for that. Even if the program immediately stops - if it does so
with a panic and a stack-trace, a user will just throw up their hands in
frustration, but if it provides an actionable error-message, they can fix
that issue and retry.

Of course, the fun part about compiling a statement is that it can *also*
fail due to bugs, by the way. So, the advanced version of these rules would
attempt to distinguish between the two and panic e.g. on a syntax-error in
a string-literal (to make it easier to debug and harder to accidentally put
into production) and return an error in external error conditions. I have
some code that does such checks.

Axel

[1] Corollary, of course, is "don't put stack-traces into your errors" :)


> Any comments?
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/25204eae-8550-4a78-94a3-6a63e9906f20%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/25204eae-8550-4a78-94a3-6a63e9906f20%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHxO4W7KHXCK-P8tZZz2g2yctL4HcoU%3D3ZfDY%2B-E5KRdg%40mail.gmail.com.

Reply via email to