package agentidp import ( "encoding/json" "fmt" ) // AgentIdPError is returned for all API and network failures. // It implements the error interface. type AgentIdPError struct { // Code is a machine-readable error code (e.g. "AgentNotFoundError"). Code string // Message is a human-readable description. Message string // HTTPStatus is the HTTP response status code, or 0 for network errors. HTTPStatus int // Details contains additional structured context, if provided by the API. Details map[string]interface{} } // Error implements the error interface. func (e *AgentIdPError) Error() string { return e.Message } // apiErrorBody is the standard JSON error body from the AgentIdP REST API. type apiErrorBody struct { Code string `json:"code"` Message string `json:"message"` Details map[string]interface{} `json:"details,omitempty"` } // oauth2ErrorBody is the standard JSON error body from OAuth 2.0 token endpoints. type oauth2ErrorBody struct { Error string `json:"error"` ErrorDescription string `json:"error_description"` } // parseAPIError attempts to unmarshal a JSON response body into an AgentIdPError. // Falls back to a generic UNKNOWN_ERROR if the body cannot be parsed. func parseAPIError(body []byte, status int) *AgentIdPError { var apiErr apiErrorBody if err := json.Unmarshal(body, &apiErr); err == nil && apiErr.Code != "" { return &AgentIdPError{ Code: apiErr.Code, Message: apiErr.Message, HTTPStatus: status, Details: apiErr.Details, } } return &AgentIdPError{ Code: "UNKNOWN_ERROR", Message: fmt.Sprintf("unexpected HTTP %d", status), HTTPStatus: status, } } // parseOAuth2Error attempts to unmarshal a JSON response body into an AgentIdPError // using the OAuth 2.0 error format. Falls back to UNKNOWN_ERROR on parse failure. func parseOAuth2Error(body []byte, status int) *AgentIdPError { var oauthErr oauth2ErrorBody if err := json.Unmarshal(body, &oauthErr); err == nil && oauthErr.Error != "" { return &AgentIdPError{ Code: oauthErr.Error, Message: oauthErr.ErrorDescription, HTTPStatus: status, } } return &AgentIdPError{ Code: "UNKNOWN_ERROR", Message: fmt.Sprintf("unexpected HTTP %d", status), HTTPStatus: status, } } // newNetworkError creates an AgentIdPError for transport-level failures. func newNetworkError(cause error) *AgentIdPError { return &AgentIdPError{ Code: "NETWORK_ERROR", Message: fmt.Sprintf("network error: %s", cause.Error()), HTTPStatus: 0, } }