package node import ( "strconv" ) // if pe, ok := err.(*ProtocolError); ok { log(pe.Code, pe.Message) } type ProtocolError struct { Code int Message string } func (e *ProtocolError) Error() string { return "remote error (" + strconv.Itoa(e.Code) + "): " + e.Message } // handler := &ResponseHandler{} // if err := handler.ValidateResponse(resp, MsgPong); err != nil { return 0, err } type ResponseHandler struct{} // if err := handler.ValidateResponse(resp, MsgPong); err != nil { return 0, err } func (h *ResponseHandler) ValidateResponse(resp *Message, expectedType MessageType) error { if resp == nil { return &ProtocolError{Code: ErrCodeUnknown, Message: "nil response"} } // Check for error response if resp.Type == MsgError { var errPayload ErrorPayload if err := resp.ParsePayload(&errPayload); err != nil { return &ProtocolError{Code: ErrCodeUnknown, Message: "unable to parse error response"} } return &ProtocolError{Code: errPayload.Code, Message: errPayload.Message} } // Check expected type if resp.Type != expectedType { return &ProtocolError{Code: ErrCodeInvalidMessage, Message: "unexpected response type: expected " + string(expectedType) + ", got " + string(resp.Type)} } return nil } // var stats StatsPayload // if err := handler.ParseResponse(resp, MsgStats, &stats); err != nil { return nil, err } func (h *ResponseHandler) ParseResponse(resp *Message, expectedType MessageType, target interface{}) error { if err := h.ValidateResponse(resp, expectedType); err != nil { return err } if target != nil { if err := resp.ParsePayload(target); err != nil { return &ProtocolError{Code: ErrCodeInvalidMessage, Message: "failed to parse " + string(expectedType) + " payload: " + err.Error()} } } return nil } // if err := ValidateResponse(resp, MsgPong); err != nil { return 0, err } // delegates to DefaultResponseHandler var DefaultResponseHandler = &ResponseHandler{} // if err := ValidateResponse(resp, MsgPong); err != nil { return 0, err } func ValidateResponse(resp *Message, expectedType MessageType) error { return DefaultResponseHandler.ValidateResponse(resp, expectedType) } // var stats StatsPayload // if err := ParseResponse(resp, MsgStats, &stats); err != nil { return nil, err } func ParseResponse(resp *Message, expectedType MessageType, target interface{}) error { return DefaultResponseHandler.ParseResponse(resp, expectedType, target) } // if node.IsProtocolError(err) { log("remote code:", node.GetProtocolErrorCode(err)) } func IsProtocolError(err error) bool { _, ok := err.(*ProtocolError) return ok } // code := GetProtocolErrorCode(err) // 0 when err is not a ProtocolError func GetProtocolErrorCode(err error) int { if pe, ok := err.(*ProtocolError); ok { return pe.Code } return 0 }