diff --git a/internal/ccsmp/ccsmp_container.go b/internal/ccsmp/ccsmp_container.go index 7cd272d..fe2d33a 100644 --- a/internal/ccsmp/ccsmp_container.go +++ b/internal/ccsmp/ccsmp_container.go @@ -147,7 +147,7 @@ func (opaqueContainer *SolClientOpaqueContainer) SolClientContainerGetNextField( if errorInfo != nil { // we expect and end of stream, but an error is logged if we fail if errorInfo.ReturnCode == SolClientReturnCodeFail { - logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetNextField: Unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetNextField: Unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } return "", fieldT, false } @@ -172,7 +172,7 @@ func (opaqueContainer *SolClientOpaqueContainer) SolClientContainerGetField(key if errorInfo != nil { // we expect and end of stream, but an error is logged if we fail if errorInfo.ReturnCode == SolClientReturnCodeFail { - logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetField: unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetField: unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } return fieldT, false } diff --git a/internal/ccsmp/ccsmp_core.go b/internal/ccsmp/ccsmp_core.go index 49343dd..7aa5e60 100644 --- a/internal/ccsmp/ccsmp_core.go +++ b/internal/ccsmp/ccsmp_core.go @@ -193,19 +193,46 @@ type SolClientResponseCode = C.solClient_session_responseCode_t // SolClientErrorInfoWrapper is assigned a value type SolClientErrorInfoWrapper C.solClient_errorInfo_wrapper_t +// SolClientErrorInfoWrapperDetailed is assigned a value +type SolClientErrorInfoWrapperDetailed C.solClient_errorInfo_t + func (info *SolClientErrorInfoWrapper) String() string { if info == nil { return "" } - return fmt.Sprintf("{ReturnCode: %d, SubCode: %d, ResponseCode: %d, ErrorStr: %s}", info.ReturnCode, info.SubCode, info.ResponseCode, info.GetMessageAsString()) + if info.DetailedErrorInfo == nil { + return fmt.Sprintf("{ReturnCode: %d, SubCode: nil, ResponseCode: nil, ErrorStr: nil}", info.ReturnCode) + } + detailedErrorInfo := *(info.DetailedErrorInfo) + return fmt.Sprintf("{ReturnCode: %d, SubCode: %d, ResponseCode: %d, ErrorStr: %s}", + info.ReturnCode, + detailedErrorInfo.subCode, + detailedErrorInfo.responseCode, + info.GetMessageAsString()) } // GetMessageAsString function outputs a string func (info *SolClientErrorInfoWrapper) GetMessageAsString() string { - if len(info.ErrorStr) == 0 { + if info.DetailedErrorInfo == nil || len(info.DetailedErrorInfo.errorStr) == 0 { return "" } - return C.GoString((*C.char)(&info.ErrorStr[0])) + return C.GoString((*C.char)(&info.DetailedErrorInfo.errorStr[0])) +} + +// SubCode function returns subcode if available +func (info *SolClientErrorInfoWrapper) SubCode() SolClientSubCode { + if info.DetailedErrorInfo != nil { + return (*(info.DetailedErrorInfo)).subCode + } + return SolClientSubCode(0) +} + +// ResponseCode function returns response code if available +func (info *SolClientErrorInfoWrapper) ResponseCode() SolClientResponseCode { + if info.DetailedErrorInfo != nil { + return (*(info.DetailedErrorInfo)).responseCode + } + return SolClientResponseCode(0) } // Definition of structs returned from this package to be used externally @@ -486,7 +513,7 @@ func (session *SolClientSession) SolClientSessionGetRXStat(stat SolClientStatsRX }) // we should not in normal operation encounter an error fetching stats, but just in case... if err != nil { - logging.Default.Warning("Encountered error loading core rx stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode)) + logging.Default.Warning("Encountered error loading core rx stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode())) } return value } @@ -497,7 +524,7 @@ func (session *SolClientSession) SolClientSessionGetTXStat(stat SolClientStatsTX return C.solClient_session_getTxStat(session.pointer, C.solClient_stats_tx_t(stat), (C.solClient_stats_pt)(unsafe.Pointer(&value))) }) if err != nil { - logging.Default.Warning("Encountered error loading core stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode)) + logging.Default.Warning("Encountered error loading core stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode())) } return value } @@ -621,17 +648,28 @@ func NewSessionReplyDispatch(id uint64) uintptr { return uintptr(id) } +// GetLastErrorInfoReturnCodeOnly returns a SolClientErrorInfoWrapper with only the ReturnCode field set. +// This adds a function call on failure paths, but we'd be passing strings around in that case anyways and it should +// happen rarely, so it's fine to slow it down a bit more if it means avoiding code duplication. See this function's +// usage in GetLastErrorInfo() and handleCcsmpError to see where the duplicated code would otherwise have been. +func GetLastErrorInfoReturnCodeOnly(returnCode SolClientReturnCode) *SolClientErrorInfoWrapper { + errorInfo := &SolClientErrorInfoWrapper{} + errorInfo.ReturnCode = returnCode + return errorInfo +} + // GetLastErrorInfo should NOT be called in most cases as it is dependent on the thread. // Unless you know that the goroutine running the code will not be interrupted, do NOT // call this function! func GetLastErrorInfo(returnCode SolClientReturnCode) *SolClientErrorInfoWrapper { - errorInfo := &SolClientErrorInfoWrapper{} - errorInfo.ReturnCode = returnCode + errorInfo := GetLastErrorInfoReturnCodeOnly(returnCode) if returnCode != SolClientReturnCodeNotFound { + detailedErrorInfo := C.solClient_errorInfo_t{} solClientErrorInfoPt := C.solClient_getLastErrorInfo() - errorInfo.SubCode = solClientErrorInfoPt.subCode - errorInfo.ResponseCode = solClientErrorInfoPt.responseCode - C.strcpy((*C.char)(&errorInfo.ErrorStr[0]), (*C.char)(&solClientErrorInfoPt.errorStr[0])) + detailedErrorInfo.subCode = solClientErrorInfoPt.subCode + detailedErrorInfo.responseCode = solClientErrorInfoPt.responseCode + C.strcpy((*C.char)(&detailedErrorInfo.errorStr[0]), (*C.char)(&solClientErrorInfoPt.errorStr[0])) + errorInfo.DetailedErrorInfo = &detailedErrorInfo } return errorInfo } @@ -649,8 +687,12 @@ func handleCcsmpError(f func() SolClientReturnCode) *SolClientErrorInfoWrapper { defer runtime.UnlockOSThread() returnCode := f() - if returnCode != SolClientReturnCodeOk && returnCode != SolClientReturnCodeInProgress { + if returnCode == SolClientReturnCodeFail || returnCode == SolClientReturnCodeNotReady { + // Return full error struct if rc requires additional error info. return GetLastErrorInfo(returnCode) + } else if returnCode != SolClientReturnCodeOk && returnCode != SolClientReturnCodeInProgress { + // Return partial error if not ok but not failure so that caller can parse on rc + return GetLastErrorInfoReturnCodeOnly(returnCode) } return nil } diff --git a/internal/ccsmp/ccsmp_helper.h b/internal/ccsmp/ccsmp_helper.h index 8aea8f3..04f2d8e 100644 --- a/internal/ccsmp/ccsmp_helper.h +++ b/internal/ccsmp/ccsmp_helper.h @@ -26,9 +26,7 @@ typedef struct solClient_errorInfo_wrapper { solClient_returnCode_t ReturnCode; - solClient_subCode_t SubCode; - solClient_session_responseCode_t ResponseCode; - char ErrorStr[SOLCLIENT_ERRORINFO_STR_SIZE]; + solClient_errorInfo_t * DetailedErrorInfo; } solClient_errorInfo_wrapper_t; /** diff --git a/internal/ccsmp/ccsmp_message.go b/internal/ccsmp/ccsmp_message.go index 804f21d..28ca15a 100644 --- a/internal/ccsmp/ccsmp_message.go +++ b/internal/ccsmp/ccsmp_message.go @@ -89,9 +89,12 @@ func SolClientMessageGetBinaryAttachmentAsBytes(messageP SolClientMessagePt) ([] }) if errorInfo != nil { if errorInfo.ReturnCode == SolClientReturnCodeFail { - logging.Default.Warning(fmt.Sprintf("Encountered error fetching payload as bytes: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Warning(fmt.Sprintf("Encountered error fetching payload as bytes: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) + return nil, false + } else if errorInfo.ReturnCode != SolClientReturnCodeOk { + logging.Default.Debug(fmt.Sprintf("Did not find payload as bytes: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) + return nil, false } - return nil, false } return C.GoBytes(dataPtr, C.int(size)), true } @@ -105,9 +108,12 @@ func SolClientMessageGetXMLAttachmentAsBytes(messageP SolClientMessagePt) ([]byt }) if errorInfo != nil { if errorInfo.ReturnCode == SolClientReturnCodeFail { - logging.Default.Warning(fmt.Sprintf("Encountered error fetching XML payload as bytes: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Warning(fmt.Sprintf("Encountered error fetching XML payload as bytes: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) + return nil, false + } else if errorInfo.ReturnCode != SolClientReturnCodeOk { + logging.Default.Debug(fmt.Sprintf("Did not find XML payload as bytes: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) + return nil, false } - return nil, false } return C.GoBytes(dataPtr, C.int(size)), true } @@ -132,7 +138,7 @@ func SolClientMessageGetBinaryAttachmentAsString(messageP SolClientMessagePt) (s }) if errorInfo != nil { if errorInfo.ReturnCode == SolClientReturnCodeFail { - logging.Default.Warning(fmt.Sprintf("Encountered error fetching payload as string: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Warning(fmt.Sprintf("Encountered error fetching payload as string: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } return "", false } @@ -156,7 +162,7 @@ func SolClientMessageGetBinaryAttachmentAsStream(messageP SolClientMessagePt) (* }) if errorInfo != nil { if errorInfo.ReturnCode == SolClientReturnCodeFail { - logging.Default.Warning(fmt.Sprintf("Encountered error fetching payload as stream: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Warning(fmt.Sprintf("Encountered error fetching payload as stream: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } return nil, false } @@ -174,7 +180,7 @@ func SolClientMessageGetBinaryAttachmentAsMap(messageP SolClientMessagePt) (*Sol }) if errorInfo != nil { if errorInfo.ReturnCode == SolClientReturnCodeFail { - logging.Default.Warning(fmt.Sprintf("Encountered error fetching payload as stream: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Warning(fmt.Sprintf("Encountered error fetching payload as stream: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } return nil, false } diff --git a/internal/ccsmp/ccsmp_message_tracing.go b/internal/ccsmp/ccsmp_message_tracing.go index 7dad11f..13dbbee 100644 --- a/internal/ccsmp/ccsmp_message_tracing.go +++ b/internal/ccsmp/ccsmp_message_tracing.go @@ -81,7 +81,7 @@ func SolClientMessageGetTraceContextTraceID(messageP SolClientMessagePt, context fmt.Sprintf( "Encountered error fetching Creation context traceID prop: %s, subcode: %d", errorInfo.GetMessageAsString(), - errorInfo.SubCode)) + errorInfo.SubCode())) } return [TraceIDSize]byte{}, errorInfo } @@ -122,7 +122,7 @@ func SolClientMessageGetTraceContextSpanID(messageP SolClientMessagePt, contextT fmt.Sprintf( "Encountered error fetching Creation context spanID prop: %s, subcode: %d", errorInfo.GetMessageAsString(), - errorInfo.SubCode)) + errorInfo.SubCode())) } return [SpanIDSize]byte{}, errorInfo } @@ -161,7 +161,7 @@ func SolClientMessageGetTraceContextSampled(messageP SolClientMessagePt, context fmt.Sprintf( "Encountered error fetching Creation context sampled prop: %s, subcode: %d", errorInfo.GetMessageAsString(), - errorInfo.SubCode)) + errorInfo.SubCode())) } return false, errorInfo } @@ -198,7 +198,7 @@ func SolClientMessageGetTraceContextTraceState(messageP SolClientMessagePt, cont fmt.Sprintf( "Encountered error fetching Creation contex traceState prop: %s, subcode: %d", errorInfo.GetMessageAsString(), - errorInfo.SubCode)) + errorInfo.SubCode())) } return "", errorInfo } @@ -336,7 +336,7 @@ func SolClientMessageGetBaggage(messageP SolClientMessagePt) (string, *SolClient fmt.Sprintf( "Encountered error fetching baggage: %s, subcode: %d", errorInfo.GetMessageAsString(), - errorInfo.SubCode)) + errorInfo.SubCode())) } return "", errorInfo } diff --git a/internal/ccsmp/cgo_helpers.go b/internal/ccsmp/cgo_helpers.go index d123eac..378c3ac 100644 --- a/internal/ccsmp/cgo_helpers.go +++ b/internal/ccsmp/cgo_helpers.go @@ -19,6 +19,8 @@ package ccsmp /* #include #include + +#include "./ccsmp_helper.h" */ import "C" import "unsafe" @@ -53,3 +55,20 @@ func ToCArray(arr []string, nullTerminated bool) (cArray **C.char, freeArray fun } return (**C.char)(unsafe.Pointer(&cArr[0])), freeFunction } + +// NewInternalSolClientErrorInfoWrapper manually creates a Go representation of the error struct usually passed to the +// Go API by CCSMP. This function is intended to be used only when such an error struct is required but cannot be +// provided by CCSMP. +func NewInternalSolClientErrorInfoWrapper(returnCode SolClientReturnCode, subCode SolClientSubCode, responseCode SolClientResponseCode, errorInfo string) *SolClientErrorInfoWrapper { + errorInfoWrapper := SolClientErrorInfoWrapper{} + errorInfoWrapper.ReturnCode = returnCode + detailedErrorInfo := C.solClient_errorInfo_t{} + detailedErrorInfo.subCode = subCode + detailedErrorInfo.responseCode = responseCode + for i := 0; i < len(errorInfo) && i < len(detailedErrorInfo.errorStr)-1; i++ { + detailedErrorInfo.errorStr[i] = (C.char)(errorInfo[i]) + } + detailedErrorInfo.errorStr[len(detailedErrorInfo.errorStr)-1] = '\x00' + errorInfoWrapper.DetailedErrorInfo = &detailedErrorInfo + return &errorInfoWrapper +} diff --git a/internal/impl/core/error.go b/internal/impl/core/error.go index 240484a..8dea6a3 100644 --- a/internal/impl/core/error.go +++ b/internal/impl/core/error.go @@ -33,7 +33,7 @@ func ToNativeError(err ErrorInfo, args ...string) error { if len(args) > 0 { prefix = args[0] } - nativeError := solace.NewNativeError(prefix+err.GetMessageAsString(), subcode.Code(err.SubCode)) + nativeError := solace.NewNativeError(prefix+err.GetMessageAsString(), subcode.Code(err.SubCode())) switch nativeError.SubCode() { case subcode.LoginFailure: return solace.NewError(&solace.AuthenticationError{}, constants.LoginFailure+nativeError.Error(), nativeError) diff --git a/internal/impl/core/events.go b/internal/impl/core/events.go index 4ca3d32..e1c3bb9 100644 --- a/internal/impl/core/events.go +++ b/internal/impl/core/events.go @@ -151,7 +151,7 @@ func (events *ccsmpBackedEvents) eventCallback(sessionEvent ccsmp.SolClientSessi logging.Default.Debug(fmt.Sprintf("Retrieved Last Error Info: %s", lastErrorInfo)) } var err error - if lastErrorInfo.SubCode != ccsmp.SolClientSubCodeOK { + if lastErrorInfo.SubCode() != ccsmp.SolClientSubCodeOK { err = ToNativeError(lastErrorInfo) } for _, eventHandler := range eventHandlers { diff --git a/internal/impl/core/receiver.go b/internal/impl/core/receiver.go index fafd06f..6adccb8 100644 --- a/internal/impl/core/receiver.go +++ b/internal/impl/core/receiver.go @@ -346,7 +346,7 @@ func (receiver *ccsmpBackedReceiver) NewPersistentReceiver(properties []string, flowEventCallback := func(flowEvent ccsmp.SolClientFlowEvent, responseCode ccsmp.SolClientResponseCode, info string) { lastErrorInfo := ccsmp.GetLastErrorInfo(0) var err error - if lastErrorInfo.SubCode != ccsmp.SolClientSubCodeOK { + if lastErrorInfo.SubCode() != ccsmp.SolClientSubCodeOK { err = ToNativeError(lastErrorInfo) } eventCallback(flowEvent, &flowEventInfo{err: err, infoString: info}) diff --git a/internal/impl/core/transport.go b/internal/impl/core/transport.go index 6f5e199..adbc8ce 100644 --- a/internal/impl/core/transport.go +++ b/internal/impl/core/transport.go @@ -157,14 +157,14 @@ func (transport *ccsmpTransport) Close() error { func destroySession(session *ccsmp.SolClientSession) { err := session.SolClientSessionDestroy() if err != nil { - logging.Default.Error(fmt.Sprintf("an error occurred while cleaning up session: %s (subcode %d)", err.GetMessageAsString(), err.SubCode)) + logging.Default.Error(fmt.Sprintf("an error occurred while cleaning up session: %s (subcode %d)", err.GetMessageAsString(), err.SubCode())) } } func destroyContext(context *ccsmp.SolClientContext) { err := context.SolClientContextDestroy() if err != nil { - logging.Default.Error(fmt.Sprintf("an error occurred while cleaning up context: %s (subcode %d)", err.GetMessageAsString(), err.SubCode)) + logging.Default.Error(fmt.Sprintf("an error occurred while cleaning up context: %s (subcode %d)", err.GetMessageAsString(), err.SubCode())) } } diff --git a/internal/impl/message/inbound_message_impl.go b/internal/impl/message/inbound_message_impl.go index c407351..4b04ad4 100644 --- a/internal/impl/message/inbound_message_impl.go +++ b/internal/impl/message/inbound_message_impl.go @@ -70,7 +70,7 @@ func (message *InboundMessageImpl) Dispose() { func freeInboundMessage(message *InboundMessageImpl) { err := ccsmp.SolClientMessageFree(&message.messagePointer) if err != nil && logging.Default.IsErrorEnabled() { - logging.Default.Error("encountered unexpected error while freeing message pointer: " + err.GetMessageAsString() + " [sub code = " + strconv.Itoa(int(err.SubCode)) + "]") + logging.Default.Error("encountered unexpected error while freeing message pointer: " + err.GetMessageAsString() + " [sub code = " + strconv.Itoa(int(err.SubCode())) + "]") } } @@ -81,7 +81,7 @@ func (message *InboundMessageImpl) GetDestinationName() string { destName, errorInfo := ccsmp.SolClientMessageGetDestinationName(message.messagePointer) if errorInfo != nil { if errorInfo.ReturnCode == ccsmp.SolClientReturnCodeFail { - logging.Default.Debug(fmt.Sprintf("Unable to retrieve the destination this message was published to: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("Unable to retrieve the destination this message was published to: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } } return destName @@ -94,7 +94,7 @@ func (message *InboundMessageImpl) GetTimeStamp() (time.Time, bool) { t, errInfo := ccsmp.SolClientMessageGetTimestamp(message.messagePointer) if errInfo != nil { if errInfo.ReturnCode == ccsmp.SolClientReturnCodeFail { - logging.Default.Debug(fmt.Sprintf("Encountered error retrieving Sender Timestamp: %s, subcode: %d", errInfo.GetMessageAsString(), errInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("Encountered error retrieving Sender Timestamp: %s, subcode: %d", errInfo.GetMessageAsString(), errInfo.SubCode())) } return t, false } @@ -107,7 +107,7 @@ func (message *InboundMessageImpl) GetSenderTimestamp() (time.Time, bool) { t, errInfo := ccsmp.SolClientMessageGetSenderTimestamp(message.messagePointer) if errInfo != nil { if errInfo.ReturnCode == ccsmp.SolClientReturnCodeFail { - logging.Default.Debug(fmt.Sprintf("Encountered error retrieving Sender Timestamp: %s, subcode: %d", errInfo.GetMessageAsString(), errInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("Encountered error retrieving Sender Timestamp: %s, subcode: %d", errInfo.GetMessageAsString(), errInfo.SubCode())) } return t, false } @@ -119,7 +119,7 @@ func (message *InboundMessageImpl) GetSenderID() (string, bool) { id, errInfo := ccsmp.SolClientMessageGetSenderID(message.messagePointer) if errInfo != nil { if errInfo.ReturnCode == ccsmp.SolClientReturnCodeFail { - logging.Default.Debug(fmt.Sprintf("Encountered error retrieving Sender ID: %s, subcode: %d", errInfo.GetMessageAsString(), errInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("Encountered error retrieving Sender ID: %s, subcode: %d", errInfo.GetMessageAsString(), errInfo.SubCode())) } return id, false } @@ -136,7 +136,7 @@ func (message *InboundMessageImpl) GetReplicationGroupMessageID() (rgmid.Replica rmidPt, errInfo := ccsmp.SolClientMessageGetRGMID(message.messagePointer) if errInfo != nil { if errInfo.ReturnCode == ccsmp.SolClientReturnCodeFail { - logging.Default.Debug(fmt.Sprintf("Encountered error retrieving ReplicationGroupMessageID: %s, subcode: %d", errInfo.GetMessageAsString(), errInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("Encountered error retrieving ReplicationGroupMessageID: %s, subcode: %d", errInfo.GetMessageAsString(), errInfo.SubCode())) } return nil, false } @@ -197,7 +197,7 @@ func GetReplyToDestinationName(message *InboundMessageImpl) (string, bool) { destName, errorInfo := ccsmp.SolClientMessageGetReplyToDestinationName(message.messagePointer) if errorInfo != nil { if errorInfo.ReturnCode == ccsmp.SolClientReturnCodeFail { - logging.Default.Debug(fmt.Sprintf("Unable to retrieve the reply to destination this message was published to: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("Unable to retrieve the reply to destination this message was published to: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } return destName, false } diff --git a/internal/impl/message/message_impl.go b/internal/impl/message/message_impl.go index 6ed5b73..177fb2a 100644 --- a/internal/impl/message/message_impl.go +++ b/internal/impl/message/message_impl.go @@ -47,14 +47,14 @@ func (message *MessageImpl) GetProperties() (propMap sdt.Map) { opaqueContainer, errorInfo := ccsmp.SolClientMessageGetUserPropertyMap(message.messagePointer) if errorInfo != nil { if errorInfo.ReturnCode != ccsmp.SolClientReturnCodeNotFound { - logging.Default.Warning(fmt.Sprintf("Encountered error fetching user property map: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Warning(fmt.Sprintf("Encountered error fetching user property map: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } return nil } defer func() { errorInfo := opaqueContainer.SolClientContainerClose() if errorInfo != nil && logging.Default.IsDebugEnabled() { - logging.Default.Debug(fmt.Sprintf("Encountered error while closing container: %s, errorCode %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("Encountered error while closing container: %s, errorCode %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } }() return parseMap(opaqueContainer) @@ -67,14 +67,14 @@ func (message *MessageImpl) GetProperty(propertyName string) (propertyValue sdt. opaqueContainer, errorInfo := ccsmp.SolClientMessageGetUserPropertyMap(message.messagePointer) if errorInfo != nil { if errorInfo.ReturnCode != ccsmp.SolClientReturnCodeNotFound { - logging.Default.Warning(fmt.Sprintf("Encountered error fetching user property map: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Warning(fmt.Sprintf("Encountered error fetching user property map: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } return nil, false } defer func() { errorInfo := opaqueContainer.SolClientContainerClose() if errorInfo != nil && logging.Default.IsDebugEnabled() { - logging.Default.Debug(fmt.Sprintf("Encountered error while closing container: %s, errorCode %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("Encountered error while closing container: %s, errorCode %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } }() val, ok := opaqueContainer.SolClientContainerGetField(propertyName) @@ -98,6 +98,7 @@ func (message *MessageImpl) HasProperty(propertyName string) bool { func (message *MessageImpl) GetPayloadAsBytes() (bytes []byte, ok bool) { binaryAttachmentBytes, binaryAttachmentOk := ccsmp.SolClientMessageGetBinaryAttachmentAsBytes(message.messagePointer) xmlContentBytes, xmlContentOk := ccsmp.SolClientMessageGetXMLAttachmentAsBytes(message.messagePointer) + //if binaryAttachmentOk && xmlContentOk && binaryAttachmentBytes == nil && xmlContentBytes == nil { if binaryAttachmentOk && xmlContentOk { logging.Default.Warning(fmt.Sprintf("Internal error: message %p contained multiple payloads", message)) return nil, false @@ -143,7 +144,7 @@ func (message *MessageImpl) GetPayloadAsMap() (sdt.Map, bool) { defer func() { errorInfo := container.SolClientContainerClose() if errorInfo != nil && logging.Default.IsDebugEnabled() { - logging.Default.Debug(fmt.Sprintf("Encountered error while closing container: %s, errorCode %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("Encountered error while closing container: %s, errorCode %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } }() parsedMap := parseMap(container) @@ -165,7 +166,7 @@ func (message *MessageImpl) GetPayloadAsStream() (sdtStream sdt.Stream, ok bool) defer func() { errorInfo := container.SolClientContainerClose() if errorInfo != nil && logging.Default.IsDebugEnabled() { - logging.Default.Debug(fmt.Sprintf("Encountered error while closing container: %s, errorCode %d", errorInfo.GetMessageAsString(), errorInfo.SubCode)) + logging.Default.Debug(fmt.Sprintf("Encountered error while closing container: %s, errorCode %d", errorInfo.GetMessageAsString(), errorInfo.SubCode())) } }() parsedStream := parseStream(container) diff --git a/internal/impl/message/outbound_message_impl.go b/internal/impl/message/outbound_message_impl.go index 0a8344d..c7071fe 100644 --- a/internal/impl/message/outbound_message_impl.go +++ b/internal/impl/message/outbound_message_impl.go @@ -79,7 +79,7 @@ func (message *OutboundMessageImpl) Dispose() { func freeOutboundMessage(message *OutboundMessageImpl) { err := ccsmp.SolClientMessageFree(&message.messagePointer) if err != nil && logging.Default.IsErrorEnabled() { - logging.Default.Error("encountered unexpected error while freeing message pointer: " + err.GetMessageAsString() + " [sub code = " + strconv.Itoa(int(err.SubCode)) + "]") + logging.Default.Error("encountered unexpected error while freeing message pointer: " + err.GetMessageAsString() + " [sub code = " + strconv.Itoa(int(err.SubCode())) + "]") } } diff --git a/internal/impl/publisher/direct_message_publisher_impl_test.go b/internal/impl/publisher/direct_message_publisher_impl_test.go index 1c9af36..b37aa56 100644 --- a/internal/impl/publisher/direct_message_publisher_impl_test.go +++ b/internal/impl/publisher/direct_message_publisher_impl_test.go @@ -921,10 +921,10 @@ func TestDirectMessagePublisherPublishFunctionalityDirect(t *testing.T) { subCode := 21 internalPublisher.publish = func(message ccsmp.SolClientMessagePt) core.ErrorInfo { - return &ccsmp.SolClientErrorInfoWrapper{ - ReturnCode: ccsmp.SolClientReturnCodeFail, - SubCode: ccsmp.SolClientSubCode(subCode), - } + return ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCodeFail, + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This error info is generated") } err = publisher.Publish(testMessage, testTopic) @@ -1109,10 +1109,10 @@ func TestDirectMessagePublisherTaskFailure(t *testing.T) { subCode := 23 internalPublisher.publish = func(message ccsmp.SolClientMessagePt) core.ErrorInfo { - return &ccsmp.SolClientErrorInfoWrapper{ - ReturnCode: ccsmp.SolClientReturnCodeFail, - SubCode: ccsmp.SolClientSubCode(subCode), - } + return ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCodeFail, + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error info") } testMessage, _ := message.NewOutboundMessage() diff --git a/internal/impl/publisher/persistent_message_publisher_impl_test.go b/internal/impl/publisher/persistent_message_publisher_impl_test.go index e31f57d..5b3c464 100644 --- a/internal/impl/publisher/persistent_message_publisher_impl_test.go +++ b/internal/impl/publisher/persistent_message_publisher_impl_test.go @@ -1002,10 +1002,10 @@ func TestPersistentMessagePublisherPublishFunctionalityPersistent(t *testing.T) subCode := 21 internalPublisher.publish = func(message ccsmp.SolClientMessagePt) core.ErrorInfo { - return &ccsmp.SolClientErrorInfoWrapper{ - ReturnCode: ccsmp.SolClientReturnCodeFail, - SubCode: ccsmp.SolClientSubCode(subCode), - } + return ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCodeFail, + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error info") } err = publisher.Publish(testMessage, testTopic, nil, nil) @@ -1190,10 +1190,10 @@ func TestPersistentMessagePublisherTaskFailure(t *testing.T) { subCode := 23 internalPublisher.publish = func(message ccsmp.SolClientMessagePt) core.ErrorInfo { - return &ccsmp.SolClientErrorInfoWrapper{ - ReturnCode: ccsmp.SolClientReturnCodeFail, - SubCode: ccsmp.SolClientSubCode(subCode), - } + return ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCodeFail, + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error info") } testMessage, _ := message.NewOutboundMessage() diff --git a/internal/impl/publisher/request_reply_message_publisher_impl_test.go b/internal/impl/publisher/request_reply_message_publisher_impl_test.go index 24d5fab..cef5378 100644 --- a/internal/impl/publisher/request_reply_message_publisher_impl_test.go +++ b/internal/impl/publisher/request_reply_message_publisher_impl_test.go @@ -770,10 +770,10 @@ func TestRequestReplyStartFailedToGetReplyTo(t *testing.T) { internalPublisher.requestor = func() core.Requestor { mock := &mockRequestor{} mock.addRequestorReplyHandler = func(handler core.RequestorReplyHandler) (string, func() (messageID uint64, correlationID string), core.ErrorInfo) { - return "", nil, &ccsmp.SolClientErrorInfoWrapper{ - ReturnCode: ccsmp.SolClientReturnCodeFail, - SubCode: ccsmp.SolClientSubCode(subCode), - } + return "", nil, ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCodeFail, + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error info") } return mock } @@ -1424,10 +1424,10 @@ func TestRequestReplyMessagePublisherPublishFunctionalityDirect(t *testing.T) { subCode := 21 // ClientDeleteInProgress , note this subcode does not matter just need a subcode that is not OK. internalPublisher.publish = func(message ccsmp.SolClientMessagePt) core.ErrorInfo { - return &ccsmp.SolClientErrorInfoWrapper{ - ReturnCode: ccsmp.SolClientReturnCodeFail, - SubCode: ccsmp.SolClientSubCode(subCode), - } + return ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCodeFail, + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error info") } err = publisher.Publish(testMessage, testReplyHandler, testTopic, testTimeout, nil /*properties*/, nil /*usercontext*/) @@ -1633,10 +1633,10 @@ func TestRequestReplyMessagePublisherTaskFailureReplyOutcome(t *testing.T) { subCode := 58 // MissingReplyTo, note this subcode does not matter and does not represent a real scenario internalPublisher.publish = func(message ccsmp.SolClientMessagePt) core.ErrorInfo { - return &ccsmp.SolClientErrorInfoWrapper{ - ReturnCode: ccsmp.SolClientReturnCodeFail, - SubCode: ccsmp.SolClientSubCode(subCode), - } + return ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCodeFail, + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error info") } testMessage, _ := message.NewOutboundMessage() diff --git a/internal/impl/receiver/direct_message_receiver_impl_test.go b/internal/impl/receiver/direct_message_receiver_impl_test.go index 438ae33..e7b006f 100644 --- a/internal/impl/receiver/direct_message_receiver_impl_test.go +++ b/internal/impl/receiver/direct_message_receiver_impl_test.go @@ -498,9 +498,11 @@ func TestDirectReceiverSubscribeWithError(t *testing.T) { } topic := "some topic" subscription := resource.TopicSubscriptionOf(topic) - solClientErr := &ccsmp.SolClientErrorInfoWrapper{ - SubCode: 123, - } + subCode := 123 + solClientErr := ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCode(0), + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error info") for _, fn := range subscriptionFunctions { receiver.subscriptions = []string{} internalReceiverCalled := false @@ -642,9 +644,11 @@ func TestDirectReceiverUnsubscribeWithError(t *testing.T) { } topic := "some topic" subscription := resource.TopicSubscriptionOf(topic) - solClientErr := &ccsmp.SolClientErrorInfoWrapper{ - SubCode: 123, - } + subCode := 123 + solClientErr := ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCode(0), + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error info") for _, fn := range unsubscriptionFunctions { receiver.subscriptions = []string{topic} internalReceiverCalled := false diff --git a/internal/impl/receiver/persistent_message_receiver_impl.go b/internal/impl/receiver/persistent_message_receiver_impl.go index f6af154..ac39ff4 100644 --- a/internal/impl/receiver/persistent_message_receiver_impl.go +++ b/internal/impl/receiver/persistent_message_receiver_impl.go @@ -275,7 +275,7 @@ func (receiver *persistentMessageReceiverImpl) provisionEndpoint() error { if receiver.doCreateMissingResources && receiver.queue.IsDurable() { errInfo := receiver.internalReceiver.ProvisionEndpoint(receiver.queue.GetName(), receiver.queue.IsExclusivelyAccessible()) if errInfo != nil { - if subcode.Code(errInfo.SubCode) == subcode.EndpointAlreadyExists { + if subcode.Code(errInfo.SubCode()) == subcode.EndpointAlreadyExists { receiver.logger.Info("Endpoint '" + receiver.queue.GetName() + "' already exists") } else { receiver.logger.Warning("Failed to provision endpoint '" + receiver.queue.GetName() + "', " + errInfo.GetMessageAsString()) @@ -1128,7 +1128,7 @@ func (receiver *persistentMessageReceiverImpl) run() { } else { errInfo := receiver.internalFlow.Ack(msgID) if errInfo != nil { - receiver.logger.Warning("Failed to acknowledge message: " + errInfo.GetMessageAsString() + ", sub code: " + fmt.Sprint(errInfo.SubCode)) + receiver.logger.Warning("Failed to acknowledge message: " + errInfo.GetMessageAsString() + ", sub code: " + fmt.Sprint(errInfo.SubCode())) } } } diff --git a/internal/impl/receiver/persistent_message_receiver_impl_test.go b/internal/impl/receiver/persistent_message_receiver_impl_test.go index 1c30e8f..ba480b1 100644 --- a/internal/impl/receiver/persistent_message_receiver_impl_test.go +++ b/internal/impl/receiver/persistent_message_receiver_impl_test.go @@ -411,9 +411,11 @@ func TestPersistentReceiverSubscribeWithError(t *testing.T) { } topic := "some topic" subscription := resource.TopicSubscriptionOf(topic) - solClientErr := &ccsmp.SolClientErrorInfoWrapper{ - SubCode: 123, - } + subCode := 123 + solClientErr := ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCode(0), + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error ErrorInfo") for _, fn := range subscriptionFunctions { receiver.subscriptions = []string{} internalReceiverCalled := false @@ -560,9 +562,11 @@ func TestPersistentReceiverUnsubscribeWithError(t *testing.T) { } topic := "some topic" subscription := resource.TopicSubscriptionOf(topic) - solClientErr := &ccsmp.SolClientErrorInfoWrapper{ - SubCode: 123, - } + subCode := 123 + solClientErr := ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCode(0), + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error info") for _, fn := range unsubscriptionFunctions { receiver.subscriptions = []string{topic} internalReceiverCalled := false diff --git a/internal/impl/receiver/request_reply_message_receiver_impl_test.go b/internal/impl/receiver/request_reply_message_receiver_impl_test.go index 0a967cf..79ea972 100644 --- a/internal/impl/receiver/request_reply_message_receiver_impl_test.go +++ b/internal/impl/receiver/request_reply_message_receiver_impl_test.go @@ -56,10 +56,10 @@ func TestReplierFailedSendReply(t *testing.T) { replier := &replierImpl{} internalReplier := &mockReplier{} - replyErrInfo := &ccsmp.SolClientErrorInfoWrapper{ - ReturnCode: ccsmp.SolClientReturnCodeFail, - SubCode: ccsmp.SolClientSubCode(subCode), - } + replyErrInfo := ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCodeFail, + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "") internalReplier.sendReply = func(replyMsg core.ReplyPublishable) core.ErrorInfo { return replyErrInfo @@ -84,11 +84,10 @@ func TestReplierWouldBlockSendReply(t *testing.T) { replier := &replierImpl{} internalReplier := &mockReplier{} - replyErrInfo := &ccsmp.SolClientErrorInfoWrapper{ - ReturnCode: ccsmp.SolClientReturnCodeWouldBlock, - SubCode: ccsmp.SolClientSubCode(subCode), - } - + replyErrInfo := ccsmp.NewInternalSolClientErrorInfoWrapper(ccsmp.SolClientReturnCodeWouldBlock, + ccsmp.SolClientSubCode(subCode), + ccsmp.SolClientResponseCode(0), + "This is a generated error info.") internalReplier.sendReply = func(replyMsg core.ReplyPublishable) core.ErrorInfo { return replyErrInfo }