errors icon indicating copy to clipboard operation
errors copied to clipboard

Raising custom error types/ const errors

Open andig opened this issue 6 years ago • 7 comments

The io package declares an EOF error like this:

var EOF = errors.New("EOF")

using this pattern to raise custom errors leads to ugly stack traces since the errors are generated during intialization, not when they happen:

github.com/andig/gosml.init
        /Users/andig/Documents/htdocs/go/src/github.com/andig/gosml/crc16.go:32
main.init
        <autogenerated>:1
runtime.main
        /usr/local/opt/go/libexec/src/runtime/proc.go:186
runtime.goexit
        /usr/local/opt/go/libexec/src/runtime/asm_amd64.s:2361

in fact, the entire call stack of where is error happens is lost which means using the error type is impossible.

How could one implement custom error types or errors the can be behaviour-checked according to your blog article?

andig avatar Jun 18 '18 16:06 andig

you can always wrap it again

CreatCodeBuild avatar Jun 18 '18 17:06 CreatCodeBuild

https://dave.cheney.net/2016/04/07/constant-errors

Which contains, "Although, you really shouldn’t be using sentinel errors anyway."

puellanivis avatar Jun 18 '18 18:06 puellanivis

The errors package explicitly makes it hard to use for Singleton errors.

I suggest using the stdlib errors.new and wrapping when needed.

On 19 Jun 2018, at 03:50, 哲の王 [email protected] wrote:

you can always wrap it again

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

davecheney avatar Jun 18 '18 20:06 davecheney

The errors package explicitly makes it hard to use for Singleton errors.

Understood and thank you for your blog posts.

I suggest using the stdlib errors.new and wrapping when needed.

That works but still doesn't deliver and entirely "clean" stack trace as I'd desire.

Bottom line- with my limited go experience- seems to be that you cannot test wrapped (top-level) errors for behaviour (need to use causer instead) and stack traces will contain both inner error creation plus wrapping when "throwing" for that reason.

andig avatar Jun 19 '18 06:06 andig

I recommend using pkg/errors.New at the point you need to return an error.

You won’t be able to compare that error value to another other than nil, but that’s the point.

If you do need to use a sentinel error value, then pkg/errors is not the tool for you. It’s deliberately design so that it’s errors are not comparable for reasons that I outlined in my blog post.

On 19 Jun 2018, at 16:13, andig [email protected] wrote:

The errors package explicitly makes it hard to use for Singleton errors.

Understood and thank you for your blog posts.

I suggest using the stdlib errors.new and wrapping when needed.

That works but still doesn't deliver and entirely "clean" stack trace as I'd desire. But it seems to be as good as it will get.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

davecheney avatar Jun 19 '18 06:06 davecheney

Indeed, I recall in a previous bug/feature discussion, I suggested making a nicer Sentinel const-compatible type, and the recommendation was, “if we make it easier, people will use it, and we would like to actually discourage it.“

But regardless, a “good sentinel” value can be had with just a few lines of code. Sure the type ends up being unique to your package, (and hopefully actually unexported) but these are parts of what should hopefully make sentinel errors better than var EOF = errors.New("EOF") with all the pitfalls of being able to then monkey around with the sentinel.

As a note, the stdlib errors is not const-compatible, so. :neutral_face:

puellanivis avatar Jun 19 '18 09:06 puellanivis

I'm sorry I haven't replied before now. I'm going to close this issue as there is nothing to do here; this package isn't what you what, its designed in a way that is incompatible with your requirements.

davecheney avatar Oct 08 '18 21:10 davecheney