theazureshadow
theazureshadow

Reputation: 10059

Create custom error with stack trace

I'm trying to use go-errors to include stack traces with errors I generate. I have a custom HttpError type that I also want to include stack traces. My initial thought was to do this with an embed, but I can't seem to embed it since the name of the class (Error) is the same as the name of one of the methods.

package netutil

import (
  "github.com/go-errors/errors"
)

type HttpError struct {
  status int
  *errors.Error
}

func (h *HttpError) Error() string {
  return "Failed"
}

func NewHttpError(status int, message string) *HttpError {
  return &HttpError{
    status,
    errors.New(message),
  }
}

I receive the following error:

tmp_error.go:12: type HttpError has both field and method named Error

Any suggestions?

Upvotes: 2

Views: 1339

Answers (2)

Mitar
Mitar

Reputation: 7070

Since this question was asked, Go errors patterns have evolved quite a bit. There is now a standard way of wrapping errors into new errors with potentially additional information. This is then used by packages like gitlab.com/tozd/go/errors (disclaimer: I am its maintainer) to add additional information, e.g., stack traces, or structured details.

So your example could then look like:

package netutil

import (
  "gitlab.com/tozd/go/errors"
)

type HttpError struct {
  status int
}

func (h *HttpError) Error() string {
  return "Failed"
}

func NewHttpError(status int, message string) error {
  return errors.WithMessage(&HttpError{status}, message)
}

errors.WithMessage prepends the message to the error message of the HttpError error and records a stack trace (if the error does not already have it, which HttpError does not). You can format then the error to get the stack trace:

fmt.Printf("%+v\n", err)

Upvotes: 0

evanmcdonnal
evanmcdonnal

Reputation: 48124

Why not just name this inner error with something appropriate like inner-error or stack-trace?

type HttpError struct {
  status int
  StackTace *errors.Error
}

Seems to be fairly common practice in classes used for error handling in other languages/frameworks like .NET and Java.

Another option would be to concatenate your custom message with the inner error using fmt.Sprintf at the time you create the error, keeping it all as one.

errors.New(fmt.Sprintf("This proprietary error happened! Stack trace: %s", message));

If you did that you wouldn't implement func (h *HttpError) Error() since you'd be relying on the embedded error for this.

Upvotes: 1

Related Questions