Skip to content

Commit 2e2f6b1

Browse files
author
Pascal van Leeuwen
committed
improve no-op qos error response
1 parent a172d21 commit 2e2f6b1

3 files changed

Lines changed: 57 additions & 18 deletions

File tree

qos/noop/context.go

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,6 @@ import (
1111
"github.com/buildwithgrove/path/protocol"
1212
)
1313

14-
// clientRespMsgNoProtocolEndpoints is the error message sent to clients when
15-
// the underlying protocol fails to register any endpoint responses with the NoOp QoS service.
16-
// This can occur due to:
17-
// - User error: invalid service ID in the request's HTTP header
18-
// - Protocol error: selected endpoint failed to provide a valid response
19-
// - System timeout: no endpoints responded within the allowed time window
20-
const clientRespMsgNoProtocolEndpoints = "NoOp QoS service error: No responses received from any service endpoints. Please verify your service ID and retry."
21-
2214
// requestContext implements all the functionality required by gateway.RequestQoSContext interface.
2315
var _ gateway.RequestQoSContext = &requestContext{}
2416

@@ -45,7 +37,7 @@ type requestContext struct {
4537

4638
// presetFailureResponse, if set, is used to return a preconstructed response to the user.
4739
// This is used by the conductor of the requestContext instance, e.g. if reading the HTTP request's body fails.
48-
presetFailureResponse *HTTPResponse
40+
presetFailureResponse pathhttp.HTTPResponse
4941
}
5042

5143
// GetServicePayload returns the payload to be sent to a service endpoint.
@@ -68,7 +60,10 @@ func (rc *requestContext) GetServicePayloads() []protocol.Payload {
6860
// UpdateWithResponse is NOT safe for concurrent use
6961
// Implements the gateway.RequestQoSContext interface.
7062
func (rc *requestContext) UpdateWithResponse(endpointAddr protocol.EndpointAddr, endpointSerializedResponse []byte) {
71-
rc.receivedResponses = append(rc.receivedResponses, endpointResponse{EndpointAddr: endpointAddr, ResponseBytes: endpointSerializedResponse})
63+
rc.receivedResponses = append(rc.receivedResponses, endpointResponse{
64+
EndpointAddr: endpointAddr,
65+
ResponseBytes: endpointSerializedResponse,
66+
})
7267
}
7368

7469
// GetHTTPResponse returns a user-facing response that fulfills the pathhttp.HTTPResponse interface.
@@ -81,10 +76,7 @@ func (rc *requestContext) GetHTTPResponse() pathhttp.HTTPResponse {
8176
}
8277

8378
if len(rc.receivedResponses) == 0 {
84-
return &HTTPResponse{
85-
httpStatusCode: http.StatusOK,
86-
payload: []byte(clientRespMsgNoProtocolEndpoints),
87-
}
79+
return getNoEndpointResponse()
8880
}
8981

9082
return &HTTPResponse{

qos/noop/errors.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package noop
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
7+
pathhttp "github.com/buildwithgrove/path/network/http"
8+
)
9+
10+
const (
11+
// errTemplate is the template for the error response to ensure
12+
// that the error response is returned in a valid JSON format.
13+
errTemplate = `{"error":"%s","msg":"%s"}`
14+
15+
// clientRespMsgNoProtocolEndpoints is the error message sent to clients when
16+
// the underlying protocol fails to register any endpoint responses with the NoOp QoS service.
17+
// This can occur due to:
18+
// - User error: invalid service ID in the request's HTTP header
19+
// - Protocol error: selected endpoint failed to provide a valid response
20+
// - System timeout: no endpoints responded within the allowed time window
21+
clientRespMsgNoProtocolEndpoints = "no-op qos service error: no responses received from any service endpoints"
22+
23+
// clientRespMsgRequestProcessingError is the error message sent to clients when
24+
// the NoOp QoS service encounters an error while reading the request body.
25+
// This can occur due to:
26+
// - User error: invalid request body caused the an error reading the request body
27+
clientRespMsgRequestProcessingError = "no-op qos service error: error processing the request"
28+
)
29+
30+
// formatJSONError creates a JSON formatted error response with the provided error and message.
31+
func formatJSONError(message string, err error) []byte {
32+
return []byte(fmt.Sprintf(errTemplate, err.Error(), message))
33+
}
34+
35+
// getRequestProcessingError creates a HTTP response for request processing errors.
36+
func getRequestProcessingError(err error) pathhttp.HTTPResponse {
37+
return &HTTPResponse{
38+
httpStatusCode: http.StatusBadRequest,
39+
payload: formatJSONError(clientRespMsgRequestProcessingError, err),
40+
}
41+
}
42+
43+
// getNoEndpointResponse creates a HTTP response for no endpoint responses.
44+
func getNoEndpointResponse() pathhttp.HTTPResponse {
45+
err := fmt.Errorf("no protocol endpoint responses")
46+
return &HTTPResponse{
47+
httpStatusCode: http.StatusInternalServerError,
48+
payload: formatJSONError(clientRespMsgNoProtocolEndpoints, err),
49+
}
50+
}

qos/noop/noop.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,7 @@ func (NoOpQoS) GetRequiredQualityChecks(_ protocol.EndpointAddr) []gateway.Reque
5656
// The returned requestContext will returns a user-facing HTTP request with the supplied error when it GetHTTPResponse method is called.
5757
func requestContextFromError(err error) *requestContext {
5858
return &requestContext{
59-
presetFailureResponse: &HTTPResponse{
60-
httpStatusCode: http.StatusOK,
61-
payload: []byte(fmt.Sprintf("Error processing the request: %v", err)),
62-
},
59+
presetFailureResponse: getRequestProcessingError(err),
6360
}
6461
}
6562

0 commit comments

Comments
 (0)