Issue #42: implement Go client session values errors and CLI
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
package mxgateway
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
pb "gitea.dohertylan.com/dohertj2/mxaccessgw/clients/go/internal/generated"
|
||||
)
|
||||
|
||||
// GatewayError wraps transport-level gRPC failures.
|
||||
type GatewayError struct {
|
||||
Op string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *GatewayError) Error() string {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
if e.Op == "" {
|
||||
return fmt.Sprintf("mxgateway: %v", e.Err)
|
||||
}
|
||||
return fmt.Sprintf("mxgateway: %s failed: %v", e.Op, e.Err)
|
||||
}
|
||||
|
||||
func (e *GatewayError) Unwrap() error {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// CommandError reports a non-OK gateway protocol status and keeps the raw
|
||||
// command reply when one exists.
|
||||
type CommandError struct {
|
||||
Op string
|
||||
Status *ProtocolStatus
|
||||
Reply *MxCommandReply
|
||||
}
|
||||
|
||||
func (e *CommandError) Error() string {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
status := e.Status
|
||||
if status == nil {
|
||||
return fmt.Sprintf("mxgateway: %s failed with missing protocol status", e.Op)
|
||||
}
|
||||
if status.GetMessage() == "" {
|
||||
return fmt.Sprintf("mxgateway: %s failed with protocol status %s", e.Op, status.GetCode())
|
||||
}
|
||||
return fmt.Sprintf("mxgateway: %s failed with protocol status %s: %s", e.Op, status.GetCode(), status.GetMessage())
|
||||
}
|
||||
|
||||
// MxAccessError reports HRESULT or MXSTATUS_PROXY failures returned by MXAccess.
|
||||
type MxAccessError struct {
|
||||
Command *CommandError
|
||||
Reply *MxCommandReply
|
||||
}
|
||||
|
||||
func (e *MxAccessError) Error() string {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
if e.Command != nil && e.Command.Status != nil && e.Command.Status.GetMessage() != "" {
|
||||
return e.Command.Error()
|
||||
}
|
||||
if e.Reply != nil && e.Reply.GetDiagnosticMessage() != "" {
|
||||
return fmt.Sprintf("mxgateway: MXAccess command %s failed: %s", e.Reply.GetKind(), e.Reply.GetDiagnosticMessage())
|
||||
}
|
||||
if e.Reply != nil && e.Reply.Hresult != nil {
|
||||
return fmt.Sprintf("mxgateway: MXAccess command %s failed with HRESULT 0x%08X", e.Reply.GetKind(), uint32(e.Reply.GetHresult()))
|
||||
}
|
||||
return "mxgateway: MXAccess command failed"
|
||||
}
|
||||
|
||||
func (e *MxAccessError) Unwrap() error {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return e.Command
|
||||
}
|
||||
|
||||
// EnsureProtocolSuccess returns a typed CommandError when status is non-OK.
|
||||
func EnsureProtocolSuccess(op string, status *ProtocolStatus, reply *MxCommandReply) error {
|
||||
if status == nil || status.GetCode() == pb.ProtocolStatusCode_PROTOCOL_STATUS_CODE_OK {
|
||||
return nil
|
||||
}
|
||||
|
||||
commandError := &CommandError{
|
||||
Op: op,
|
||||
Status: status,
|
||||
Reply: reply,
|
||||
}
|
||||
if status.GetCode() == pb.ProtocolStatusCode_PROTOCOL_STATUS_CODE_MXACCESS_FAILURE {
|
||||
return &MxAccessError{
|
||||
Command: commandError,
|
||||
Reply: reply,
|
||||
}
|
||||
}
|
||||
return commandError
|
||||
}
|
||||
|
||||
// EnsureMxAccessSuccess returns a typed MxAccessError for failing HRESULTs or
|
||||
// MXSTATUS_PROXY entries.
|
||||
func EnsureMxAccessSuccess(op string, reply *MxCommandReply) error {
|
||||
if reply == nil {
|
||||
return nil
|
||||
}
|
||||
if reply.Hresult != nil && reply.GetHresult() != 0 {
|
||||
return &MxAccessError{Reply: reply}
|
||||
}
|
||||
for _, status := range reply.GetStatuses() {
|
||||
if !StatusSucceeded(status) {
|
||||
return &MxAccessError{Reply: reply}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user