~samwhited/xmpp

c2386364233bb9aa1885349dad53ed78160a50a8 — Sam Whited 3 months ago 9075f1b
stanza: add UnmarshalError function

Signed-off-by: Sam Whited <sam@samwhited.com>
3 files changed, 29 insertions(+), 18 deletions(-)

M CHANGELOG.md
M stanza/error.go
M stanza/iq.go
M CHANGELOG.md => CHANGELOG.md +1 -0
@@ 20,6 20,7 @@ All notable changes to this project will be documented in this file.
- blocklist: new package implementing [XEP-0191: Blocking Command]
- commands: new package implementing [XEP-0050: Ad-Hoc Commands]
- stanza: implement [XEP-0203: Delayed Delivery]
- stanza: more general `UnmarshalError` function that doesn't focus on IQs


### Fixed

M stanza/error.go => stanza/error.go +25 -0
@@ 6,6 6,7 @@ package stanza

import (
	"encoding/xml"
	"errors"
	"io"

	"mellium.im/xmlstream"


@@ 401,3 402,27 @@ func (se *Error) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	}
	return nil
}

// UnmarshalError unmarshals the first stanaza error payload it finds in a token
// stream, skipping over the sender XML if it is present.
//
// If no error payload is found an error indicating that the payload was not
// found is returned.
func UnmarshalError(r xml.TokenReader) (Error, error) {
	iter := xmlstream.NewIter(r)
	for iter.Next() {
		start, p := iter.Current()
		if start.Name.Local != "error" {
			continue
		}

		d := xml.NewTokenDecoder(xmlstream.Wrap(p, *start))
		var stanzaErr Error
		decodeErr := d.Decode(&stanzaErr)
		return stanzaErr, decodeErr
	}
	if err := iter.Err(); err != nil {
		return Error{}, iter.Err()
	}
	return Error{}, errors.New("stanza: expected error payload")
}

M stanza/iq.go => stanza/iq.go +3 -18
@@ 36,26 36,11 @@ func UnmarshalIQError(r xml.TokenReader, start xml.StartElement) (IQ, error) {
		return iqStart, nil
	}

	iter := xmlstream.NewIter(r)
	for iter.Next() {
		start, p := iter.Current()
		if start.Name.Local != "error" {
			continue
		}

		d := xml.NewTokenDecoder(xmlstream.Wrap(p, *start))
		var stanzaErr Error
		decodeErr := d.Decode(&stanzaErr)
		if decodeErr != nil {
			return iqStart, decodeErr
		}
		return iqStart, stanzaErr
	}
	if err = iter.Err(); err != nil {
	stanzaErr, err := UnmarshalError(r)
	if err != nil {
		return iqStart, err
	}

	return iqStart, Error{}
	return iqStart, stanzaErr
}

// NewIQ unmarshals an XML token into a IQ.