gotest.tools icon indicating copy to clipboard operation
gotest.tools copied to clipboard

Question: how do you check error types with errors.As?

Open sevein opened this issue 9 months ago • 2 comments

Hi @dnephin!

I've been doing something like the following to check error types with errors.As:

assert.Assert(t, errors.As(err, new(*osexec.ExitError)))

It works fine, but I keep wondering if it would make sense for gotest.tools to provide a built-in assert.ErrorAs helper - something along the lines of qt.ErrorAs.

Even if we want to keep the interface simple, handling wrapped errors in Go often needs a bit of extra complexity. A helper could make these checks easier to read and more consistent. I understand that adding more surface to the interface might not be ideal, so I totally get if this doesn't fit the goals of the project. Maybe it's just worth documenting the preferred pattern somewhere?

Thank you in advance.

Related discussion: https://github.com/gotestyourself/gotest.tools/issues/272.

sevein avatar Apr 04 '25 09:04 sevein

errT, ok := errors.As(err, &errorType{})
if !ok {
    t.Fatal("got error type %T, wanted errorType", err)
}

Or

errT, ok := errors.As(err, &errorType{})
assert.Assert(ok, "got %T", err)

Generally if I'm using errors.As I think I'd want the returned type so I can check fields or methods of that type as wel.

dnephin avatar May 06 '25 03:05 dnephin

Generally if I'm using errors.As I think I'd want the returned type

Agreed. When I've added helpers for this, it looks like:

typed := helper(t, err) // this calls t.FailNow
assert.Assert(t, ... typed ...)
assert.Assert(t, ... typed ...)

I think something directly in assert could be:

typed := assert.ErrorAs[V](t, err)

If you don't want to t.FailNow, then assert.Check may be enough:

if v := new(V); assert.Check(t, errors.As(err, &v)) {
	// ...
}

cbandy avatar Aug 27 '25 13:08 cbandy