Abbreviated parameter names violate AX Principle 1 (predictable names over short names). resp → response in ValidateResponse and ParseResponse. Co-Authored-By: Charon <charon@lethean.io>
86 lines
2.9 KiB
Go
86 lines
2.9 KiB
Go
package node
|
|
|
|
import (
|
|
"strconv"
|
|
)
|
|
|
|
// if protocolError, ok := err.(*ProtocolError); ok { log(protocolError.Code, protocolError.Message) }
|
|
type ProtocolError struct {
|
|
Code int
|
|
Message string
|
|
}
|
|
|
|
func (protocolError *ProtocolError) Error() string {
|
|
return "remote error (" + strconv.Itoa(protocolError.Code) + "): " + protocolError.Message
|
|
}
|
|
|
|
// handler := &ResponseHandler{}
|
|
// if err := handler.ValidateResponse(resp, MsgPong); err != nil { return 0, err }
|
|
type ResponseHandler struct{}
|
|
|
|
// if err := handler.ValidateResponse(response, MsgPong); err != nil { return 0, err }
|
|
func (handler *ResponseHandler) ValidateResponse(response *Message, expectedType MessageType) error {
|
|
if response == nil {
|
|
return &ProtocolError{Code: ErrCodeUnknown, Message: "nil response"}
|
|
}
|
|
|
|
// Check for error response
|
|
if response.Type == MsgError {
|
|
var errPayload ErrorPayload
|
|
if err := response.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 response.Type != expectedType {
|
|
return &ProtocolError{Code: ErrCodeInvalidMessage, Message: "unexpected response type: expected " + string(expectedType) + ", got " + string(response.Type)}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// var stats StatsPayload
|
|
// if err := handler.ParseResponse(response, MsgStats, &stats); err != nil { return nil, err }
|
|
func (handler *ResponseHandler) ParseResponse(response *Message, expectedType MessageType, target interface{}) error {
|
|
if err := handler.ValidateResponse(response, expectedType); err != nil {
|
|
return err
|
|
}
|
|
|
|
if target != nil {
|
|
if err := response.ParsePayload(target); err != nil {
|
|
return &ProtocolError{Code: ErrCodeInvalidMessage, Message: "failed to parse " + string(expectedType) + " payload: " + err.Error()}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// if err := ValidateResponse(response, MsgPong); err != nil { return 0, err } // delegates to DefaultResponseHandler
|
|
var DefaultResponseHandler = &ResponseHandler{}
|
|
|
|
// if err := ValidateResponse(response, MsgPong); err != nil { return 0, err }
|
|
func ValidateResponse(response *Message, expectedType MessageType) error {
|
|
return DefaultResponseHandler.ValidateResponse(response, expectedType)
|
|
}
|
|
|
|
// var stats StatsPayload
|
|
// if err := ParseResponse(response, MsgStats, &stats); err != nil { return nil, err }
|
|
func ParseResponse(response *Message, expectedType MessageType, target interface{}) error {
|
|
return DefaultResponseHandler.ParseResponse(response, 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 protocolError, ok := err.(*ProtocolError); ok {
|
|
return protocolError.Code
|
|
}
|
|
return 0
|
|
}
|