feat: add dependency shutdown and configurable service endpoints
This commit is contained in:
@@ -57,6 +57,9 @@ func (c *Context) writeResult(result response.Result) (err error) {
|
||||
if err != nil {
|
||||
return apierrors.Internal(err)
|
||||
}
|
||||
if result.PreserveStatus {
|
||||
payload.Status = result.Status
|
||||
}
|
||||
if payload.Status < 200 || payload.Status > 599 {
|
||||
return apierrors.Internal(fmt.Errorf("response encoder returned invalid status %d", payload.Status))
|
||||
}
|
||||
@@ -66,6 +69,41 @@ func (c *Context) writeResult(result response.Result) (err error) {
|
||||
return c.WriteResponse(payload.Status, payload.Header, payload.Body)
|
||||
}
|
||||
|
||||
// RespondStatus uses the current response format and error catalog, but keeps
|
||||
// the explicit HTTP status even if a catalog/custom encoder selects another.
|
||||
// This is useful for protocol endpoints such as health probes. Ordinary
|
||||
// business handlers should use OK/Created or return their error as usual.
|
||||
func (c *Context) RespondStatus(status int, data any, err error) error {
|
||||
if c.Responded() {
|
||||
return nil
|
||||
}
|
||||
if status < 200 || status > 599 || status == 204 || status == 205 || status == 304 {
|
||||
return apierrors.Internal(fmt.Errorf("response requires a body-bearing HTTP status"))
|
||||
}
|
||||
result := response.Result{Status: status, Code: "OK", Message: "success", Data: data,
|
||||
RequestID: c.RequestID(), PreserveStatus: true}
|
||||
if err != nil {
|
||||
failure := c.ResolveError(err)
|
||||
failure.Status = status
|
||||
c.failure = failure
|
||||
result.Code, result.Message, result.BusinessCode = failure.Code, failure.Message, failure.BusinessCode
|
||||
result.Err, result.Failed = err, true
|
||||
}
|
||||
writeErr := c.writeResult(result)
|
||||
if writeErr != nil && !c.Responded() {
|
||||
// A broken encoder must not fall through to a business error policy
|
||||
// that acknowledges failures with HTTP 200. Commit a bodyless failure.
|
||||
failureStatus := status
|
||||
if failureStatus < 400 {
|
||||
failureStatus = http.StatusInternalServerError
|
||||
}
|
||||
c.failure = c.ResolveError(writeErr)
|
||||
c.failure.Status = failureStatus
|
||||
_ = c.WriteResponse(failureStatus, nil, nil)
|
||||
}
|
||||
return writeErr
|
||||
}
|
||||
|
||||
// Bytes, Text and XML are explicit wire responses; they bypass any envelope.
|
||||
func (c *Context) Bytes(status int, contentType string, body []byte) error {
|
||||
return c.WriteResponse(status, http.Header{"Content-Type": {contentType}}, body)
|
||||
|
||||
Reference in New Issue
Block a user