功能增加

This commit is contained in:
andy committed 2026-09-11 15:33:18 +08:00
1 parent b340fc7ad7
commit f1993eb388
69 files changed
+2243 -162

No files matched your search

+51 -10
View File
@@ -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) {