[go-nuts] Best Practices for Error Handling in Go APIs

2025-02-03 Thread Byungjun You


In Java, checked exceptions allow developers to define in advance which 
exceptions a function can throw. However, it seems that Go does not have 
such a feature. Would it be considered a best practice in Go to document 
the possible errors that an API function can return? Additionally, what are 
some best practices that API providers can follow to help API users handle 
errors effectively?

-- 
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 visit 
https://groups.google.com/d/msgid/golang-nuts/328fdaf4-69ad-4ac0-bcb3-3f687331c64bn%40googlegroups.com.


[go-nuts] Re: Best Practices for Error Handling in Go APIs

2025-02-06 Thread Byungjun You
Hi Jeremy, I really appreciate all the materials you have shared. 

I could understand that wrapping errors with informative messages is one of 
important best practice treating errors. I'll keep it mind that :)

It was also very helpful to read errors section in Effective Go which you 
have shared.
https://go.dev/doc/effective_go#errors

Thank you.
2025년 2월 4일 화요일 오전 10시 40분 49초 UTC+9에 Jeremy French님이 작성:

> I don't know if it qualifies as "best practice" but I think it would 
> certainly qualify as convention to put the error as the last returned 
> value.  It is also extremely common to name the error "err", though that 
> would have little impact on API consumers as they can rename it whatever 
> they want. 
>
> It's also quite common at this point to wrap your errors with 
> fmt.Errorf(), which allows errors.Is() to match the root error, or anywhere 
> up the error chain, which can be convenient for your consumers. But I think 
> I would dare to say that it's best practice to only wrap an error if you 
> have something meaningful to add to it.  For example "no such file or 
> directory" is less helpful than "config: no such file or directory." but 
> "can't find file: no such file or directory" doesn't add anything.  I would 
> also say that it's (somewhat) considered best practice to keep your errors 
> terse and written for the developers, rather than flowery descriptive text 
> written for the end user.  If you need text for the end user, translate it 
> at the point of intercepting the error and doing something with it.
>
> And of course, I believe Effective Go <https://go.dev/doc/effective_go> has 
> a bit to say on the subject.
>
> On Monday, February 3, 2025 at 6:01:59 AM UTC-5 Byungjun You wrote:
>
>> In Java, checked exceptions allow developers to define in advance which 
>> exceptions a function can throw. However, it seems that Go does not have 
>> such a feature. Would it be considered a best practice in Go to document 
>> the possible errors that an API function can return? Additionally, what are 
>> some best practices that API providers can follow to help API users handle 
>> errors effectively?
>>
>

-- 
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 visit 
https://groups.google.com/d/msgid/golang-nuts/5f5f944a-1f8e-4f7e-8af6-3241409e6c91n%40googlegroups.com.


Re: [go-nuts] Best Practices for Error Handling in Go APIs

2025-02-06 Thread Byungjun You
Hi Mike, thank you so much for sharing your thoughts and all those 
resources with concrete examples. Those really help me to understand how 
errors in go work and how it is different from errors in Java. 

Based on what you've shared, here's how I understand it:
In essence, because an error in Go is just a value, there’s no built-in way 
to signal which specific errors might be returned except through 
documentation. However, since an error is a value, we can also enrich it 
with additional context like user-friendly messages, stack traces, and more.
Plus, sentinel errors are one way to expose API errors and once we exposed 
those to API users, it is very important to stick to it and not to change.

And I found the below article very interesting. Please check it out when 
you have time.
https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully

Thank you again for your sharing. 

2025년 2월 4일 화요일 오전 3시 2분 37초 UTC+9에 Mike Schinkel님이 작성:

On Feb 3, 2025, at 6:01 AM, Byungjun You  wrote:

In Java, checked exceptions allow developers to define in advance which 
exceptions a function can throw. However, it seems that Go does not have 
such a feature. Would it be considered a best practice in Go to document 
the possible errors that an API function can return? Additionally, what are 
some best practices that API providers can follow to help API users handle 
errors effectively?

In Go, errors are values[1] meaning most in the Go community frown on 
try-catch style exception handling as in Java. 

Each function in Go which can generate an error will typically return that 
error as an additional value; e.g.:

func (d Data) getValue() (value any, err error) {
   if d.value == nil {
  return nil, errors.New("value as not been set")
   }
   if reflect.ValueOf(d.value).IsZero() {
  return nil, errors.New("value is empty")
   }
   return value,err
}

Then getValue() would be called like this:

value, err := data.getValue()

See https://go.dev/play/p/PciRk_t_UaV for full working example.

In some cases — though not as many as I would like — Go developers often 
create sentinel values that might look like this:

var (
  ErrValueNotSet  = errors.New("value as not been set")
  ErrValueIsEmpty = errors.New("value is empty")
)

Then callers can check them using errors.Is() like so:

  if errors.Is(err, ErrValueNotSet) {...}
  if errors.Is(err, ErrValueIsEmpty) {...}

See https://go.dev/play/p/pamY1pcAoVP for a full working example.

A common sentinel error value from the Go std lib is io.EOF[2]

However, AFAIK, there is no way programmatically to determine which errors 
a Go function might return at this time. It would be nice if there were 
some built-in mechanism for doing that using the reflect package, but I 
would not expect that to be added as I cannot imagine how it could be 
implemented without slowing down compilation. Unfortunately.

As for best practices, IMO that would be to define sentinel error variables 
instead of errors created inline with errors.New() or fmt.Errorf() for all 
errors that your function may return, and then use errors.Join() to join 
with any errors returned by a function your function called before 
returning to the caller. Then document your sentinel error variables and 
commit to not renaming or removing them in future versions of your API.

Does that answer your question?

-Mike
[1] https://go.dev/blog/errors-are-values
[2] 
https://github.com/golang/go/blob/beea7c1ba6a93c2a2991e79936ac4050bae851c4/src/io/io.go#L44

-- 
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 visit 
https://groups.google.com/d/msgid/golang-nuts/f3871600-0bd2-4a91-b94b-f24fa7828a40n%40googlegroups.com.


Re: [go-nuts] Re: Getting new coverage output format from go test -cover

2025-01-23 Thread Byungjun You
I'm so glad to hear it helped you!

> I wonder where the blog author found that flag? It's not exposed in `go 
test`

I guess "-test.gocoverdir" parameter is not exposed to go test users well. 
There is an another comment that it was very hard to find documents about 
"-test.gocoverdir" parameter. :(
https://groups.google.com/g/golang-nuts/c/tg0ZrfpRMSg/m/Co8U64SAAgAJ
> Btw, I can't find documentation on -test.gocoverdir in Google 
<https://www.google.com/search?q=golang+%22-test.gocoverdir%22&oq=golang+%22-test.gocoverdir%22&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIHCAEQABiiBNIBCTEyODgzajBqN6gCALACAA&sourceid=chrome&ie=UTF-8#ip=1>,
 
except the insides of code. Also `go help testflag | grep gocoverdir` 
doesn't return anything -- in go1.21.0.
2025년 1월 22일 수요일 오전 10시 52분 54초 UTC+9에 Paul Chesnais (papacharlie)님이 작성:

> Oh that's perfect! Pretty much what I was looking for. Let me test it and 
> get back to you.
>
> I wonder where the blog author found that flag? It's not exposed in `go 
> test`
>
> On Tuesday, January 14, 2025 at 5:27:07 AM UTC-8 Byungjun You wrote:
>
>> Have you try go test with -args -test.gocoverdir parameters?
>>
>> > go test -cover ./... -args -test.gocoverdir="{a directory where 
>> coverage reports should be generated}"
>>
>> I found this blog post is very helpful when merging unit and integration 
>> test coverage reports.
>>
>> https://dustinspecker.com/posts/go-combined-unit-integration-code-coverage/
>>
>> 2025년 1월 13일 월요일 오전 10시 13분 15초 UTC+9에 Paul Chesnais (papacharlie)님이 작성:
>>
>>> The blog post doesn't provide a way to translate the output of `go test 
>>> -coverprofile ...` (which is the so-called legacy text format) into the new 
>>> binary format, which `go tool covdata merge` expects. It only provides it 
>>> in the reverse, i.e. the new binary format to the legacy format. So it 
>>> means if I'm running my tests with multiple invocations of `go test` (e.g. 
>>> because they need to be run in different envs/different tags) there's no 
>>> easy way to get merged coverage results. Is there any way to get `go test` 
>>> to produce the new format, or to translate the text format into the new 
>>> format?
>>>
>>> On Saturday, January 11, 2025 at 9:26:40 PM UTC-5 Ian Lance Taylor wrote:
>>>
>>>> On Sat, Jan 11, 2025 at 10:07 AM Paul Chesnais (papacharlie) 
>>>>  wrote: 
>>>> > 
>>>> > Is there another forum I can ask about this? Should this be a feature 
>>>> request against the go team directly? It seems strange that the formats 
>>>> haven't been converged, or that there's no way to get the new binary 
>>>> format 
>>>> from `go test` 
>>>>
>>>> I don't really know the answer, but the blog post 
>>>>
>>>> https://go.dev/blog/integration-test-coverage#working-with-coverage-data-files
>>>>  
>>>> discusses converting between different coverage profile data formats. 
>>>> If that doesn't help, can you explain in more detail, perhaps with a 
>>>> series of commands that doesn't work as you hope? 
>>>>
>>>> Ian 
>>>>
>>>>
>>>> > On Tuesday, December 3, 2024 at 1:26:04 PM UTC-5 Paul Chesnais 
>>>> (papacharlie) wrote: 
>>>> >> 
>>>> >> Hello, 
>>>> >> 
>>>> >> I'd like to be able to merge the data from the output of `go test 
>>>> -cover` with the output of a run using `go build -cover` but it seems that 
>>>> there's no way to translate the "legacy" format from go test into the new 
>>>> binary format. This means it's not possible to use the built-in tooling 
>>>> like `go tool covdata merge`. There is of course the possibility of 
>>>> translating the binary format back into the legacy format using textfmt 
>>>> but 
>>>> then there's still no good way to merge the coverage data without using 
>>>> some custom tooling like https://github.com/wadey/gocovmerge. 
>>>> >> 
>>>> >> As far as I can tell there's also no way to get clever and get `go 
>>>> test -c` to build with the binary with the `-cover` flag because that 
>>>> build 
>>>> flag gets eaten up by `go test`. It seems there's no way to get the new 
>>>> coverage format from go test, unless I'm missing something? 
>>>> >> 
>>>> >> Just looking for any insights on this, thanks in advance! 
>>>> >> 
>>>> >> Paul 
>>>> > 
>>>> > -- 
>>>> > 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...@googlegroups.com. 
>>>> > To view this discussion visit 
>>>> https://groups.google.com/d/msgid/golang-nuts/d7b799e4-49a6-417d-8b13-65b5b244c11cn%40googlegroups.com.
>>>>  
>>>>
>>>>
>>>

-- 
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 visit 
https://groups.google.com/d/msgid/golang-nuts/5c480e18-e6bb-4ba3-a3f4-43a20cd914d1n%40googlegroups.com.


Re: [go-nuts] Re: Getting new coverage output format from go test -cover

2025-01-14 Thread Byungjun You
Have you try go test with -args -test.gocoverdir parameters?

> go test -cover ./... -args -test.gocoverdir="{a directory where coverage 
reports should be generated}"

I found this blog post is very helpful when merging unit and integration 
test coverage reports.
https://dustinspecker.com/posts/go-combined-unit-integration-code-coverage/

2025년 1월 13일 월요일 오전 10시 13분 15초 UTC+9에 Paul Chesnais (papacharlie)님이 작성:

> The blog post doesn't provide a way to translate the output of `go test 
> -coverprofile ...` (which is the so-called legacy text format) into the new 
> binary format, which `go tool covdata merge` expects. It only provides it 
> in the reverse, i.e. the new binary format to the legacy format. So it 
> means if I'm running my tests with multiple invocations of `go test` (e.g. 
> because they need to be run in different envs/different tags) there's no 
> easy way to get merged coverage results. Is there any way to get `go test` 
> to produce the new format, or to translate the text format into the new 
> format?
>
> On Saturday, January 11, 2025 at 9:26:40 PM UTC-5 Ian Lance Taylor wrote:
>
>> On Sat, Jan 11, 2025 at 10:07 AM Paul Chesnais (papacharlie) 
>>  wrote: 
>> > 
>> > Is there another forum I can ask about this? Should this be a feature 
>> request against the go team directly? It seems strange that the formats 
>> haven't been converged, or that there's no way to get the new binary format 
>> from `go test` 
>>
>> I don't really know the answer, but the blog post 
>>
>> https://go.dev/blog/integration-test-coverage#working-with-coverage-data-files
>>  
>> discusses converting between different coverage profile data formats. 
>> If that doesn't help, can you explain in more detail, perhaps with a 
>> series of commands that doesn't work as you hope? 
>>
>> Ian 
>>
>>
>> > On Tuesday, December 3, 2024 at 1:26:04 PM UTC-5 Paul Chesnais 
>> (papacharlie) wrote: 
>> >> 
>> >> Hello, 
>> >> 
>> >> I'd like to be able to merge the data from the output of `go test 
>> -cover` with the output of a run using `go build -cover` but it seems that 
>> there's no way to translate the "legacy" format from go test into the new 
>> binary format. This means it's not possible to use the built-in tooling 
>> like `go tool covdata merge`. There is of course the possibility of 
>> translating the binary format back into the legacy format using textfmt but 
>> then there's still no good way to merge the coverage data without using 
>> some custom tooling like https://github.com/wadey/gocovmerge. 
>> >> 
>> >> As far as I can tell there's also no way to get clever and get `go 
>> test -c` to build with the binary with the `-cover` flag because that build 
>> flag gets eaten up by `go test`. It seems there's no way to get the new 
>> coverage format from go test, unless I'm missing something? 
>> >> 
>> >> Just looking for any insights on this, thanks in advance! 
>> >> 
>> >> Paul 
>> > 
>> > -- 
>> > 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...@googlegroups.com. 
>> > To view this discussion visit 
>> https://groups.google.com/d/msgid/golang-nuts/d7b799e4-49a6-417d-8b13-65b5b244c11cn%40googlegroups.com.
>>  
>>
>>
>

-- 
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 visit 
https://groups.google.com/d/msgid/golang-nuts/78bac578-2371-4adb-8157-732b021660fbn%40googlegroups.com.