14 gob.RegisterName("*udpapi.APIError", &APIError{})
15 // implements APIReply
16 gob.RegisterName("*udpapi.errorWrapper", &errorWrapper{})
17 // implements APIReply
18 gob.RegisterName("*udpapi.genericReply", &genericReply{})
21 type APIError struct {
26 func (err *APIError) Error() string {
27 return fmt.Sprint(err.Code, err.Desc)
30 // The interface for all UDP API replies.
32 // The user should call Error() to verify if the API call completed successfully.
33 type APIReply interface {
34 // An opaque string used as identifying tag.
37 // The integer code for the reply.
40 // The description for the reply (first line minus code).
43 // Slice with all lines of the reply.
46 // Indicates whether the network code detected truncation.
49 // Returns the underlying error, if any.
53 type errorWrapper struct {
57 func (_ *errorWrapper) Tag() string {
61 func (w *errorWrapper) Code() int {
62 switch e := w.err.(type) {
70 func (w *errorWrapper) Text() string {
71 switch e := w.err.(type) {
79 func (w *errorWrapper) Lines() []string {
80 return []string{w.Text()}
83 func (_ *errorWrapper) Truncated() bool {
87 func (w *errorWrapper) Error() error {
91 func newErrorWrapper(err error) APIReply {
97 type genericReply struct {
107 // The value APIReply.Error() returns after a timeout.
108 // Unrelated to the server-side error 604 TIMEOUT - DELAY AND RESUBMIT.
109 var TimeoutError = errors.New("Timeout")
111 func newGenericReply(raw []byte) (r *genericReply) {
113 lines := strings.Split(str, "\n")
114 parts := strings.Fields(lines[0])
121 // Drop lines that are only whitespace
122 for len(lines) > 0 && strings.TrimSpace(lines[len(lines)-1]) == "" {
123 lines = lines[:len(lines)-1]
126 // XXX: REQUIRES that the tag is not parsable as a base 10 number.
127 // Just prepending any sent tag with 'T' ought to be enough
130 code, err := strconv.ParseInt(parts[0], 10, 16)
131 if err != nil && len(parts) > 1 {
133 code, err = strconv.ParseInt(parts[1], 10, 16)
136 text = strings.Join(parts[2:], " ")
138 } else if len(parts) > 1 {
139 text = strings.Join(parts[1:], " ")
143 // 720-799 range is for notifications
144 // 799 is an API server shutdown notice, so I guess it's okay to be an error
145 if err == nil && code < 200 || (code > 299 && code < 720) || code > 798 {
146 e = &APIError{Code: int(code), Desc: text}
149 return &genericReply{
158 func (r *genericReply) Tag() string {
162 func (r *genericReply) Code() int {
166 func (r *genericReply) Text() string {
170 func (r *genericReply) Lines() []string {
174 func (r *genericReply) Truncated() bool {
178 func (r *genericReply) Error() error {