On Wed, 12 Feb 2025 at 09:21, cpu...@gmail.com <cpui...@gmail.com> wrote:

> I've had some ongoing confusion about using errors.As (see
> https://play.golang.com/p/m4_cXCzOViD). The issue I'm having is this part
> of the contract:
>
> > An error matches target if the error's concrete value is assignable to
> the value pointed to by target
>
> I always expected (yes, I know), that base and pointer receivers are
> interchangeable. This is not the case (see playground). This seems to make
> using it error-prone as you'll always need to carefully think about the
> return type of the function invoked. While the contract is always error, a
> function may return a base or a pointer error type. This influences how
> using errors.As must be done.
>
> Are there best practices for:
> - return base vs. pointer errors
>

The best practice is pointer errors. I would have personally preferred to
live in a world where value errors are better (in particular, it would be
pretty nice to be able to compare full error values using `==` in tests).
But the issue you have discovered is pretty much exactly, why pointer
errors are better.

If you declare `Error()` on a value receiver, then both `err.(YourErr)` and
`err.(*YourErr)` will compile just fine, as value-methods are promoted to
the pointer type. But only one of them will succeed. Similarly, both
`return YourErr{…}` and `return &YourErr{…}` will compile. So it is
somewhat easy to make a mistake that are then hard to debug in practice -
and the error paths tend to be badly tested already.

If, on the other hand, you declare it with a pointer receiver, only
`err.(*YourErr)` and `return &YourErr{…}` will compile. Meaning the
compiler ensures that you write the correct code.

errors.As is ultimately a dynamic extension of this semantic difference,
which is the problem you have stumbled on.


> - crafting  the errors.As target type without inspecting the actual
> function invoked
>
> ...and could it make sense to lessen errors.As to match pointer with
> non-pointer receivers?
>
> Thanks!
>
> --
> 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/afe2df8a-9e42-4511-abe6-8e03b906d637n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/afe2df8a-9e42-4511-abe6-8e03b906d637n%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 visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGkqHredkmZwY3m4KFcTAEuQ9aOWaCo_Aaikp1LJ3U2mA%40mail.gmail.com.

Reply via email to