功能增加
This commit is contained in:
1 parent
b340fc7ad7
commit
f1993eb388
69 files changed
+2243
-162
No files matched your search
@@ -112,7 +112,11 @@ type ProviderError struct {
|
||||
Operation string
|
||||
Status int
|
||||
Code string
|
||||
Cause error
|
||||
RequestID string
|
||||
// Detail is opt-in, bounded and redacted by the provider-specific adapter.
|
||||
// Error() deliberately never includes it.
|
||||
Detail string
|
||||
Cause error
|
||||
}
|
||||
|
||||
func (e *ProviderError) Error() string {
|
||||
@@ -125,14 +129,15 @@ func (e *ProviderError) Error() string {
|
||||
func (e *ProviderError) Unwrap() error { return e.Cause }
|
||||
|
||||
type httpAdapter struct {
|
||||
name string
|
||||
config Config
|
||||
client HTTPClient
|
||||
submitPath func(Request) string
|
||||
queryPath func(string) string
|
||||
payload func(Request) any
|
||||
headers func(*http.Request)
|
||||
decode func([]byte) Result
|
||||
name string
|
||||
config Config
|
||||
client HTTPClient
|
||||
submitPath func(Request) string
|
||||
queryPath func(string) string
|
||||
payload func(Request) any
|
||||
headers func(*http.Request)
|
||||
decode func([]byte) Result
|
||||
failureDetail func(responseBody, requestBody []byte) string
|
||||
}
|
||||
|
||||
func (a *httpAdapter) submit(ctx context.Context, input Request) (Result, error) {
|
||||
@@ -206,6 +211,11 @@ func (a *httpAdapter) call(ctx context.Context, method, path string, body []byte
|
||||
}
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
code, requestID, errorType := inspectHTTPProviderFailure(raw, resp.Header)
|
||||
var detail string
|
||||
// Only a submission carries the original content needed for redaction.
|
||||
if operation == "submit" && a.failureDetail != nil {
|
||||
detail = a.failureDetail(raw, body)
|
||||
}
|
||||
logHTTPProviderFailure(httpProviderDiagnostic{
|
||||
Provider: a.name,
|
||||
Operation: operation,
|
||||
@@ -215,8 +225,9 @@ func (a *httpAdapter) call(ctx context.Context, method, path string, body []byte
|
||||
ErrorType: errorType,
|
||||
ErrorClass: "service",
|
||||
ElapsedMS: elapsedMilliseconds(startedAt),
|
||||
Detail: detail,
|
||||
})
|
||||
return Result{}, &ProviderError{Operation: a.name + " " + operation, Status: resp.StatusCode, Code: code}
|
||||
return Result{}, &ProviderError{Operation: a.name + " " + operation, Status: resp.StatusCode, Code: code, RequestID: requestID, Detail: detail}
|
||||
}
|
||||
if !json.Valid(raw) {
|
||||
logHTTPProviderFailure(httpProviderDiagnostic{
|
||||
@@ -238,9 +249,18 @@ type httpProviderDiagnostic struct {
|
||||
ErrorType string
|
||||
ErrorClass string
|
||||
ElapsedMS int64
|
||||
Detail string
|
||||
}
|
||||
|
||||
func logHTTPProviderFailure(diagnostic httpProviderDiagnostic) {
|
||||
if diagnostic.Detail != "" {
|
||||
log.Printf(
|
||||
"zhinian-api provider operation failed provider=%s operation=%s status=%d code=%q requestId=%q errorType=%q errorClass=%s elapsedMs=%d detail=%q",
|
||||
diagnostic.Provider, diagnostic.Operation, diagnostic.Status, diagnostic.Code, diagnostic.RequestID,
|
||||
diagnostic.ErrorType, diagnostic.ErrorClass, diagnostic.ElapsedMS, diagnostic.Detail,
|
||||
)
|
||||
return
|
||||
}
|
||||
log.Printf(
|
||||
"zhinian-api provider operation failed provider=%s operation=%s status=%d code=%q requestId=%q errorType=%q errorClass=%s elapsedMs=%d",
|
||||
diagnostic.Provider,
|
||||
@@ -269,6 +289,9 @@ func inspectHTTPProviderFailure(raw []byte, headers http.Header) (code, requestI
|
||||
metadataError["code"], metadataError["Code"],
|
||||
root["code"], root["Code"],
|
||||
), 64)
|
||||
if code == "" {
|
||||
code = parenthesizedNumericCode(stringValue(providerError["message"], root["message"]))
|
||||
}
|
||||
requestID = safeHTTPProviderDiagnosticToken(first(
|
||||
providerError["request_id"], providerError["requestId"], providerError["RequestId"], providerError["RequestID"],
|
||||
root["request_id"], root["requestId"], root["RequestId"], root["RequestID"],
|
||||
@@ -283,6 +306,24 @@ func inspectHTTPProviderFailure(raw []byte, headers http.Header) (code, requestI
|
||||
return code, requestID, errorType
|
||||
}
|
||||
|
||||
func parenthesizedNumericCode(message string) string {
|
||||
message = strings.TrimSpace(message)
|
||||
if len(message) < 3 || message[len(message)-1] != ')' {
|
||||
return ""
|
||||
}
|
||||
start := strings.LastIndexByte(message, '(')
|
||||
if start < 0 || start == len(message)-2 {
|
||||
return ""
|
||||
}
|
||||
code := message[start+1 : len(message)-1]
|
||||
for _, character := range code {
|
||||
if character < '0' || character > '9' {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return safeHTTPProviderDiagnosticToken(code, 16)
|
||||
}
|
||||
|
||||
func safeHTTPProviderDiagnosticToken(value any, maxLength int) string {
|
||||
var token string
|
||||
switch typed := value.(type) {
|
||||
|
||||
Reference in new issue
Block a user