-
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
encoding/gob: better support for error #23340
Comments
Can you show some code demonstrating where this is needed? Thanks. |
Here: https://golang.org/src/errors/errors.go We just need to add the init function to register the error struct type. |
Thanks, but I'm not asking to see the change you are proposing. I'm asking to see an example of a program that will be fixed by this change. |
@ianlancetaylor Sure, I've created this sample code to showcase the use case where you want to return an error in a response struct but you get the |
Thanks. That was much more complicated than I was expecting, and I can't run it to see the problem, but it does suggest this program: package main
import (
"bytes"
"encoding/gob"
"errors"
"log"
)
type S struct {
Err error
}
func main() {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
dec := gob.NewDecoder(&buf)
err := enc.Encode(S{errors.New("error")})
if err != nil {
log.Fatal(err)
}
var s S
err = dec.Decode(&s)
if err != nil {
log.Fatal(err)
}
} Running that program fails with
which I take to be the kind of error you are discussing. |
Change https://golang.org/cl/86456 mentions this issue: |
I think that if we decide to do this, the right approach is https://golang.org/cl/86456. That approach avoids importing encoding/gob in the errors package. We do not want the low level errors package to depend on the high level encoding/gob package. |
Yes, your example is more simple to reproduce this issue because mine is the entire use case for RPC. |
FWIW, if we need to fix this in package errors, using encoding.BinaryMarshaler or encoding.TextMarshaler would be more generally applicable than the gob-specific interfaces (and will be picked up by gob). |
/cc @robpike |
Rather than teach gob about one particular way of making errors, a better plan might be to have gob implement a fallback for errors in general. If something implements the error interface, gob could arrange to transmit the string and recover the error value on the other side, automatically. For those who want richer, type-aware semantics for errors, for example as is done in https://github.com/upspin/upspin/tree/master/errors, one can always implement one of the standard marshaling interfaces for that type, which would override the default. I've been thinking about doing this for a while; perhaps the time has come to do something. |
@robpike will look into doing something for Go 1.11. |
fwiw, I'm not convinced it is needed. The loss of type will still surprise some, but a little more insidiously. The person who expects the real type after unmarshaling will get caught out... quietly. Marshaled structs typically form part of a contract that crosses process boundaries, and these contracts should attempt to remain simple and or explicit. In the simple case I would rather see a I would say the marshalling of errors is almost binary:
In case anecdotes are in any way useful. In 4 years of working with rpc contracts across 40 services this issue has come up once, and never wrt persistence (we do gob encode for persistence). We found it quickly because it failed loudly. |
In the model I have, the special handling would occur only if the implementing type is not otherwise marshalable, which I think addresses your worry. |
Plain errors cannot be serialized over gRPC without some gob work so this change makes use of the internal BasicError type from go-plugin to send the information back to server. Upstream bug: golang/go#23340
encoding/gob has been frozen for ages now and we aren't adding more features/support to it, thus I shall close this issue. So long encoding/gob, you served us well! |
Again, we cannot use an error type here (which would be significantly more convenient) because of the following issue: <golang/go#23340>
Errors created by the errors package are not registered with
encoding/gob
which is necessary in order to send them as results of remote procedure calls.By now, returning an error from the standard library through an RPC method will cause that the receiver get an
EOF error
and the transmitter agob: type not registered for interface: errors.errorString
My proposal is add an
init()
function in the errors package to register the structerrorString
so then, developers will avoid create its own errors implementation when using RPCs.The text was updated successfully, but these errors were encountered: