package oci import ( "bytes" "encoding/json" "io" "net/http" "github.com/oracle/oci-go-sdk/v65/common" ) // scimErrorDispatcher 包装 Identity Domains 客户端的 HTTP 派发器。 // IDCS 的错误体是 SCIM 格式(detail 字段),而 SDK 只解析 code/message, // 直接透传会得到消息为空的 BadErrorResponse;这里把 4xx/5xx 的 SCIM // 错误体改写成 SDK 可解析的标准形状,让真实原因透出到面板。 type scimErrorDispatcher struct { base common.HTTPRequestDispatcher } func (d scimErrorDispatcher) Do(req *http.Request) (*http.Response, error) { resp, err := d.base.Do(req) if err != nil || resp == nil || resp.StatusCode < 400 || resp.Body == nil { return resp, err } body, readErr := io.ReadAll(resp.Body) resp.Body.Close() if readErr != nil { resp.Body = io.NopCloser(bytes.NewReader(nil)) return resp, nil } rewritten := rewriteScimError(body) resp.Body = io.NopCloser(bytes.NewReader(rewritten)) resp.ContentLength = int64(len(rewritten)) resp.Header.Del("Content-Length") return resp, nil } // rewriteScimError 提取 SCIM 错误的 detail 与 messageId 转成 // {code,message};不是 SCIM 错误体时原样返回。 func rewriteScimError(body []byte) []byte { var scim struct { Detail string `json:"detail"` Ext struct { MessageID string `json:"messageId"` } `json:"urn:ietf:params:scim:api:oracle:idcs:extension:messages:Error"` } if json.Unmarshal(body, &scim) != nil || scim.Detail == "" { return body } code := scim.Ext.MessageID if code == "" { code = "IdcsError" } std, err := json.Marshal(map[string]string{"code": code, "message": scim.Detail}) if err != nil { return body } return std }