-
Notifications
You must be signed in to change notification settings - Fork 31
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
JSON formatting for an error #21
Comments
To start the discussion properly, we should examine at least a couple of real life use cases for this feature. Those could help us answer some important questions:
All of this depends heavily on exactly how this is supposed to be used - or abused, for that matter. And this brings us to the third thing, the elephant in the room: should there be an unmarshalling for error? I intuitively resist the idea, but if we start marshalling it one way, we will get to doing it both ways - sooner or later. And if so, then marshalling must be designed so that proper unmarshalling can be implemented later without breaking the backwards compatibility. |
The biggest problem I can see is a lack of an easy access to If we would make a method like the one I listed above, |
OK, so, to make long story short, your proposal currently boils down to a public API like this:
I'm not entirely sure this is harmless. First, you could access some 'private' properties of an error that are currently out of your reach, since property key is private within some other package. Second, the presence of such API could send a wrong message about how errors should be inspected. Then again, we already have this concern about |
That's why my first proposal would be to include only printable properties, as those will be visible anyway. I am somewhat reluctant and concerned about the other version of the API method in a form of: func (e *Error) GetAllProperties(printableOnly bool) map[Property]interface {}
func (e *Error) GetAllProperties(printableOnly bool) map[string]interface {} The default for Here, also, I am reluctant to return a full My personal preference (and, already, a test implementation) is to use a method func (e *Error) GetAllPrintableProperties() map[string]interface {} [edit: added the change mentioned above to my fork, take a look if you want] |
Thank you.
This, at least, is consistent with error formatting: only the string view of printable properties is exposed. I'm not entirely happy with this 'raw string' approach, too, though. |
OK, you raised an interesting point about properties. But I see a surprising result of this - no matter whether this method will return Hence the code like: func (e *Error) GetAllPrintableProperties() map[string]interface{} {
uniq := make(map[string]interface{}, e.printablePropertyCount)
for m := e.properties; m != nil; m = m.next {
if !m.p.printable {
continue
}
if _, ok := uniq[m.p.label]; ok {
continue
}
uniq[m.p.label] = m.value
}
return uniq
} The body of this method is pretty much a cut&paste from the method If we would go into a general discussion about properties, logging, console printing, etc. - that is a different story. I generally agree with the decisions already made in the library, and how the properties are handled is solid but not perfect. If you would like to improve this further the only way around for me would be to prefix all properties with the full namespace of the error. But that is yet another ticket and, I believe, another discussion. For not it's not a problem if you look at the example struct generation code I have attached in the PR. Again, just an example, but it does address most of the problems for me at this point. Obviously, it doesn't mean we cannot improve upon it, but this overall approach is quite good enough to be used at this time... |
It would be, IMHO, reasonable to make a custom
MarshalJSON()
function to handle marshaling given Error with all printable properties and, potentially, stack trace to JSON. Maybe not all will need this, but a lot of folks are using some Web framework, and that might come in handy...As I am happy to make the implementation, I have two open questions which need an answer to address a variety of needs, not the one I see at this point:
cause
and so on? Just thinking here. One more singlecause
property with a message might be also sufficient, but I am not certain which would be more useful here...MarshalJSON
on top of that? Just asking as I am really not sure if there is something I am missing otherwise...A really quick and simple implementation can be as follows:
Happy to make a PR if that is acceptable for a larger audience
The text was updated successfully, but these errors were encountered: