Skip to content
This repository has been archived by the owner on Jul 12, 2023. It is now read-only.

Clearer outer error message for batch API #1369

Merged
merged 2 commits into from
Dec 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ This API is *not atomic* and does not follow the [typical guidelines for a batch
messages.

The server attempts to issue every code in the batch. If errors are encountered, each item in `codes` will contain the error details for
the corresponding code. The overall request will get the error status code and message of the first seen error, although some codes may have
the corresponding code. The overall request will get the error status code of the first seen error, although some codes may have
succeeded.

eg.
Expand Down
18 changes: 13 additions & 5 deletions pkg/controller/issueapi/issue_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ package issueapi

import (
"errors"
"fmt"
"net/http"
"strings"

"github.com/google/exposure-notifications-server/pkg/logging"
"github.com/google/exposure-notifications-verification-server/pkg/api"
"github.com/google/exposure-notifications-verification-server/pkg/controller"
"github.com/google/exposure-notifications-verification-server/pkg/observability"
"github.com/hashicorp/go-multierror"
)

const maxBatchSize = 10
Expand Down Expand Up @@ -79,7 +80,7 @@ func (c *Controller) HandleBatchIssue() http.Handler {
}

httpCode := http.StatusOK
var merr *multierror.Error
errCount := 0

resp.Codes = make([]*api.IssueCodeResponse, l)
for i, singleIssue := range request.Codes {
Expand All @@ -92,21 +93,28 @@ func (c *Controller) HandleBatchIssue() http.Handler {
// continue processing if when a single code issuance fails.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor, but this commend should read "continue processing even when... " ?

// if any issuance fails, the returned code is the code of the first failure.
logger.Warnw("single code issuance failed", "error", result.errorReturn)
merr = multierror.Append(merr, errors.New(result.errorReturn.Error))
errCount++
if resp.Codes[i] == nil {
resp.Codes[i] = &api.IssueCodeResponse{}
}
resp.Codes[i].ErrorCode = result.errorReturn.ErrorCode
resp.Codes[i].Error = result.errorReturn.Error
if httpCode == http.StatusOK {
httpCode = result.httpCode
resp.ErrorCode = result.errorReturn.ErrorCode
}
continue
}
}

if err := merr.ErrorOrNil(); err != nil {
resp.Error = err.Error()
if errCount > 0 {
var sb strings.Builder
sb.WriteString(fmt.Sprintf("Failed to issue %d codes.", errCount))
if succeeded := len(request.Codes) - errCount; succeeded > 0 {
sb.WriteString(fmt.Sprintf(" Issued %d codes successfully.", succeeded))
}
sb.WriteString("See each error status in the codes array.")
resp.Error = sb.String()
}

c.h.RenderJSON(w, httpCode, resp)
Expand Down