package slurm import ( "encoding/json" "fmt" "io" "net/http" ) // errorResponseFields is used to parse errors/warnings from a Slurm API error body. type errorResponseFields struct { Errors OpenapiErrors `json:"errors,omitempty"` Warnings OpenapiWarnings `json:"warnings,omitempty"` } // SlurmAPIError represents a structured error returned by the Slurm REST API. // It captures both the HTTP details and the parsed Slurm error array when available. type SlurmAPIError struct { Response *http.Response StatusCode int Errors OpenapiErrors Warnings OpenapiWarnings Message string // raw body fallback when JSON parsing fails } func (e *SlurmAPIError) Error() string { if len(e.Errors) > 0 { first := e.Errors[0] detail := "" if first.Error != nil { detail = *first.Error } else if first.Description != nil { detail = *first.Description } if detail != "" { return fmt.Sprintf("%v %v: %d %s", e.Response.Request.Method, e.Response.Request.URL, e.StatusCode, detail) } } return fmt.Sprintf("%v %v: %d %s", e.Response.Request.Method, e.Response.Request.URL, e.StatusCode, e.Message) } // IsNotFound reports whether err is a SlurmAPIError with HTTP 404 status. func IsNotFound(err error) bool { if apiErr, ok := err.(*SlurmAPIError); ok { return apiErr.StatusCode == http.StatusNotFound } return false } // CheckResponse checks the API response for errors. It returns nil if the // response is a 2xx status code. For non-2xx codes, it reads the response // body, attempts to parse structured Slurm errors, and returns a SlurmAPIError. func CheckResponse(r *http.Response) error { if c := r.StatusCode; c >= 200 && c <= 299 { return nil } data, err := io.ReadAll(r.Body) if err != nil || len(data) == 0 { return &SlurmAPIError{ Response: r, StatusCode: r.StatusCode, Message: r.Status, } } apiErr := &SlurmAPIError{ Response: r, StatusCode: r.StatusCode, Message: string(data), } // Try to extract structured errors/warnings from JSON body. var fields errorResponseFields if json.Unmarshal(data, &fields) == nil { apiErr.Errors = fields.Errors apiErr.Warnings = fields.Warnings } return apiErr }