SiaFoundation / core

Core packages for the Sia project
MIT License
51 stars 7 forks source link

Setting custom errors in Decoder.SetErr #155

Closed mike76-dev closed 3 months ago

mike76-dev commented 3 months ago

I'm struggling with this code:

// SetErr sets the Decoder's error if it has not already been set. SetErr should
// only be called from DecodeFrom methods.
func (d *Decoder) SetErr(err error) {
    if err != nil && d.err == nil {
        d.err = err
        // clear d.buf so that future reads always return zero
        d.buf = [len(d.buf)]byte{}
    }
}

I'm writing a compat code where I'm reading a struct that may or may not contain a field. If it doesn't contain that field, I need to set d.err to nil or a custom error that will indicate upstream that the compat code has executed. Currently this is not possible, because changing the d.err value is only possible when it's nil, but in my case it's EOF.

ChrisSchinnerl commented 3 months ago

SetErr is not allowing overwriting errors on purpose, because doing so might hide the root error causing an issue.

When dealing with versioning the ideal solution is usually storing/sending the version first and then continue decoding accordingly. If that is not possible, another approach is to first try and decode into the new type and if that fails try to decode into the old type. If the latter succeeds you know it was the old one. That's not as nice as the first approach but works usually.