~samwhited/xmpp

2b8d97d9d6d676ab3be8abb985e4a87318c96f96 — Sam Whited 5 years ago a5f0701
Add undefined-condition error

Fixes mellium/mel#13
3 files changed, 45 insertions(+), 4 deletions(-)

M errors/errors.go
M stream/example_test.go
M stream/streamerror.go
M errors/errors.go => errors/errors.go +4 -4
@@ 11,21 11,21 @@ import (
// New returns an error that formats as the given text and marshals with the
// given XML name and with the text as chardata.
func New(name xml.Name, text string) error {
	return &errorXML{
	return &ErrorXML{
		XMLName:  name,
		CharData: text,
	}
}

// errorXML is a trivial implementation of error intended to be marshalable and
// ErrorXML is a trivial implementation of error intended to be marshalable and
// unmarshalable as XML.
type errorXML struct {
type ErrorXML struct {
	XMLName  xml.Name
	InnerXML string `xml:",innerxml"`
	CharData string `xml:",chardata"`
}

// Satisfies the error interface and returns the error string.
func (e *errorXML) Error() string {
func (e *ErrorXML) Error() string {
	return e.CharData
}

M stream/example_test.go => stream/example_test.go +24 -0
@@ 8,6 8,8 @@ import (
	"bytes"
	"encoding/xml"
	"fmt"

	"bitbucket.org/mellium/xmpp/errors"
)

func ExampleStreamError_UnmarshalXML() {


@@ 32,3 34,25 @@ func ExampleStreamError_MarshalXML() {
	//   <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-streams"></not-authorized>
	// </stream:error>
}

func ExampleUndefinedConditionError() {
	apperr := errors.New(xml.Name{"http://example.org/ns", "app-error"}, "")
	e := UndefinedConditionError(apperr)
	b, _ := xml.MarshalIndent(e, "", "  ")
	fmt.Println(string(b))
	// Output:
	// <stream:error>
	//   <undefined-condition xmlns="urn:ietf:params:xml:ns:xmpp-streams"><app-error xmlns="http://example.org/ns"></app-error></undefined-condition>
	// </stream:error>
}

func ExampleUndefinedConditionError_errorf() {
	apperr := fmt.Errorf("Unknown error")
	e := UndefinedConditionError(apperr)
	b, _ := xml.MarshalIndent(e, "", "  ")
	fmt.Println(string(b))
	// Output:
	// <stream:error>
	//   <undefined-condition xmlns="urn:ietf:params:xml:ns:xmpp-streams">Unknown error</undefined-condition>
	// </stream:error>
}

M stream/streamerror.go => stream/streamerror.go +17 -0
@@ 7,6 7,8 @@ package stream
import (
	"encoding/xml"
	"net"

	"bitbucket.org/mellium/xmpp/errors"
)

// A list of stream errors defined in RFC 6120 §4.9.3


@@ 153,6 155,21 @@ func SeeOtherHostError(addr net.Addr) StreamError {
	return StreamError{"see-other-host", []byte(cdata)}
}

// UndefinedConditionError returns a new undefined-condition stream error with
// the given error as the inner application level error.
func UndefinedConditionError(e error) StreamError {

	var b []byte
	switch e := e.(type) {
	default:
		b = []byte(e.Error())
	case *errors.ErrorXML:
		b, _ = xml.Marshal(e)
	}

	return StreamError{"undefined-condition", b}
}

// A StreamError represents an unrecoverable stream-level error that may include
// character data or arbitrary inner XML.
type StreamError struct {