Reputation: 10059
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
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
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