-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
errors: errorString JSON marshaled #10748
Comments
Nice! thanks! |
My two cents: We should not use Error() to marshal an error. I may have a custom error like: type MyError struct {
Code int `json:"code"`
Message string `json:"message"`
}
func (err *MyError) Error() string {
return fmt.Sprintf("[%d] %s", err.Code, err.Message")
} If I JSON marshal it, nobody would expect:
instead: error: {"code": 2, "message": "this is an error"} We have to fix errorString, the error interface is just that, a interface. No Magic. |
We don't want to let the low-level errors package import the encoding/json package. That will bring encoding/json, and all of its dependencies, into all sorts of programs that don't need it. But it might work to implement a MarshalText method. |
@ianlancetaylor that makes sense! I implemented MarshalText() for you. it works perfectly fine. I also reviewed the source code of json package and looks safe. |
Let me introduce an use case: The Gin Framework provides some facilities for error management during a http request. Basically it provides a tool to collect any error or several ones. Each error is defined internally as: type errorMsg struct {
Error error `json:"error"`
Type int `json:"-"`
Meta interface{} `json:"meta"`
} Then, by using a middleware you can read the list of Simple error handler middleware: func errorHandler(c *gin.Context) {
c.Next()
if len(c.Errors) > 0 {
c.JSON(-1, c.Errors) // this does not work as expected
}
} As you can see, if the canonical value of the |
Not all errors are from errors.New, what if the error is a custom error
type implemented in user code?
I think you could just implement MarshalText method on the object
you want to marshal.
|
I know! what is the problem? I am not talking about If the error is a custom error, for example: type MyError struct {
Code int `json:"code"`
Message string `json:"message"`
}
func (err *MyError) Error() string {
return fmt.Sprintf("[%d] %s", err.Code, err.Message")
}
json.Marshal(MyError{2, "message"}) // WORKS!
json.Marshal(errors.New("message")) // DOES NOT WORK! << should be fixed (only this case) you don't really have to implement MashaslJSON() or MarshalText. The json package uses reflexion in order to generate the json string from the exported field (upper case). |
What if the error is in user code that doesn't implement MashaslJSON Fixing errors.errorString this way doesn't fix the generic problem. |
@minux ok, I see your point now.
NOTE: probably this should be implemented for XML, Gob... as well |
I don't think we can do this. Users might already depend on their To address your specific case, why don't you make your |
Design issues aside, your proposed solution introduces a circular dependency because encoding/json depends on the errors package. I do not know how you got it to work. To be sure, I just tried it: % go build You are better off handling this in your own code. |
See also #3353 |
I'm not convinced that having automatic marshaling of errors is a good thing. Implementing MarshalText on errors.errorString is never going to be that useful. For the record, our approach to error marshaling is to have a function
That function can inspect the error and decide on how it should This is not something that can be done by the individual error types themselves, |
I agree with Roger. |
I would be very convenient to be able to JSON marshal an
error
created witherrors.New()
(ie. *errorString)Right now it is just not possible.
I purpose this solution:
https://github.com/gin-gonic/go/commit/a79095c87e671d0ec2d62d96db957bfe8fb531c0
The text was updated successfully, but these errors were encountered: