package node import ( core "dappco.re/go/core" ) // ProtocolError represents an error from the remote peer. // // err := &ProtocolError{Code: ErrorCodeOperationFailed, Message: "start failed"} type ProtocolError struct { Code int Message string } func (e *ProtocolError) Error() string { return core.Sprintf("remote error (%d): %s", e.Code, e.Message) } // ResponseHandler provides helpers for handling protocol responses. // // handler := &ResponseHandler{} type ResponseHandler struct{} // ValidateResponse checks a response against the expected type. // // err := handler.ValidateResponse(resp, MessageStats) func (h *ResponseHandler) ValidateResponse(resp *Message, expectedType MessageType) error { if resp == nil { return core.E("ResponseHandler.ValidateResponse", "nil response", nil) } // Check for error response if resp.Type == MessageError { var errPayload ErrorPayload if err := resp.ParsePayload(&errPayload); err != nil { return &ProtocolError{Code: ErrorCodeUnknown, Message: "unable to parse error response"} } return &ProtocolError{Code: errPayload.Code, Message: errPayload.Message} } // Check expected type if resp.Type != expectedType { return core.E("ResponseHandler.ValidateResponse", "unexpected response type: expected "+string(expectedType)+", got "+string(resp.Type), nil) } return nil } // ParseResponse validates the response and parses the payload into the target. // // err := handler.ParseResponse(resp, MessageStats, &stats) func (h *ResponseHandler) ParseResponse(resp *Message, expectedType MessageType, target any) error { if err := h.ValidateResponse(resp, expectedType); err != nil { return err } if target != nil { if err := resp.ParsePayload(target); err != nil { return core.E("ResponseHandler.ParseResponse", "failed to parse "+string(expectedType)+" payload", err) } } return nil } // DefaultResponseHandler is the default response handler instance. var DefaultResponseHandler = &ResponseHandler{} // ValidateResponse is a convenience function using the default handler. // // err := ValidateResponse(message, MessageStats) func ValidateResponse(resp *Message, expectedType MessageType) error { return DefaultResponseHandler.ValidateResponse(resp, expectedType) } // ParseResponse is a convenience function using the default handler. // // err := ParseResponse(message, MessageStats, &stats) func ParseResponse(resp *Message, expectedType MessageType, target any) error { return DefaultResponseHandler.ParseResponse(resp, expectedType, target) } // IsProtocolError returns true if the error is a ProtocolError. // // ok := IsProtocolError(err) func IsProtocolError(err error) bool { _, ok := err.(*ProtocolError) return ok } // GetProtocolErrorCode returns the error code if err is a ProtocolError, otherwise returns 0. // // code := GetProtocolErrorCode(err) func GetProtocolErrorCode(err error) int { if pe, ok := err.(*ProtocolError); ok { return pe.Code } return 0 }