Adding flexibility to "status-code" formatting. (#25)
* Adding flexibility to "status-code" formatting. While debugging an unrelated bug in the Service Bus library, I discovered that most Service Bus endpoints will return the values "status-code" and "status-description". However, at least when one sends malformed set-session-state messages, the response will contain "statusCode" and "statusDescription". * Updating changelog * Responding to feedback. Changing statusCodeCandidate array to always be composed of consts. This makes the arrays of consts to be stylistically consistent. However, I've deliberately kept the consts scoped only to this method block in order to prevent this alternate form being used accidentally for writes elsewhere in this code-base.
This commit is contained in:
Родитель
1f0fa230ac
Коммит
dead23a105
|
@ -1,5 +1,8 @@
|
|||
# Change Log
|
||||
|
||||
## `v1.0.2`
|
||||
- adding resiliency against malformed "status-code" and "status-description" properties in rpc responses
|
||||
|
||||
## `v1.0.1`
|
||||
- bump version constant
|
||||
|
||||
|
|
35
rpc/rpc.go
35
rpc/rpc.go
|
@ -138,6 +138,8 @@ func (l *Link) RetryableRPC(ctx context.Context, times int, delay time.Duration,
|
|||
|
||||
// RPC sends a request and waits on a response for that request
|
||||
func (l *Link) RPC(ctx context.Context, msg *amqp.Message) (*Response, error) {
|
||||
const altStatusCodeKey, altDescriptionKey = "statusCode", "statusDescription"
|
||||
|
||||
l.rpcMu.Lock()
|
||||
defer l.rpcMu.Unlock()
|
||||
|
||||
|
@ -159,14 +161,37 @@ func (l *Link) RPC(ctx context.Context, msg *amqp.Message) (*Response, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
statusCode, ok := res.ApplicationProperties[statusCodeKey].(int32)
|
||||
if !ok {
|
||||
var statusCode int
|
||||
statusCodeCandidates := []string{statusCodeKey, altStatusCodeKey}
|
||||
for i := range statusCodeCandidates {
|
||||
if rawStatusCode, ok := res.ApplicationProperties[statusCodeCandidates[i]]; ok {
|
||||
if cast, ok := rawStatusCode.(int32); ok {
|
||||
statusCode = int(cast)
|
||||
break
|
||||
} else {
|
||||
return nil, errors.New("status code was not of expected type int32")
|
||||
}
|
||||
}
|
||||
}
|
||||
if statusCode == 0 {
|
||||
return nil, errors.New("status codes was not found on rpc message")
|
||||
}
|
||||
|
||||
description, ok := res.ApplicationProperties[descriptionKey].(string)
|
||||
if !ok {
|
||||
return nil, errors.New("description was not found on rpc message")
|
||||
var description string
|
||||
descriptionCandidates := []string{descriptionKey, altDescriptionKey}
|
||||
descriptionFound := false
|
||||
for i := range descriptionCandidates {
|
||||
if rawDescription, ok := res.ApplicationProperties[descriptionCandidates[i]]; ok {
|
||||
descriptionFound = true
|
||||
if description, ok = rawDescription.(string); ok {
|
||||
break
|
||||
} else {
|
||||
return nil, errors.New("status description was not of expected type string")
|
||||
}
|
||||
}
|
||||
}
|
||||
if !descriptionFound {
|
||||
return nil, errors.New("status description was not found on rpc message")
|
||||
}
|
||||
|
||||
res.Accept()
|
||||
|
|
Загрузка…
Ссылка в новой задаче