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:
Martin Strobel 2018-10-03 14:11:55 -07:00 коммит произвёл GitHub
Родитель 1f0fa230ac
Коммит dead23a105
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 33 добавлений и 5 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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()