problem.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package acme
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "net/http"
  7. )
  8. // Problem document as defined in,
  9. // https://tools.ietf.org/html/rfc7807
  10. // Problem represents an error returned by an acme server.
  11. type Problem struct {
  12. Type string `json:"type"`
  13. Detail string `json:"detail,omitempty"`
  14. Status int `json:"status,omitempty"`
  15. Instance string `json:"instance,omitempty"`
  16. SubProblems []SubProblem `json:"subproblems,omitempty"`
  17. }
  18. type SubProblem struct {
  19. Type string `json:"type"`
  20. Detail string `json:"detail"`
  21. Identifier Identifier `json:"identifier"`
  22. }
  23. // Returns a human readable error string.
  24. func (err Problem) Error() string {
  25. s := fmt.Sprintf("acme: error code %d %q: %s", err.Status, err.Type, err.Detail)
  26. if len(err.SubProblems) > 0 {
  27. for _, v := range err.SubProblems {
  28. s += fmt.Sprintf(", problem %q: %s", v.Type, v.Detail)
  29. }
  30. }
  31. if err.Instance != "" {
  32. s += ", url: " + err.Instance
  33. }
  34. return s
  35. }
  36. // Helper function to determine if a response contains an expected status code, or otherwise an error object.
  37. func checkError(resp *http.Response, expectedStatuses ...int) error {
  38. for _, statusCode := range expectedStatuses {
  39. if resp.StatusCode == statusCode {
  40. return nil
  41. }
  42. }
  43. if resp.StatusCode < 400 || resp.StatusCode >= 600 {
  44. return fmt.Errorf("acme: expected status codes: %d, got: %d %s", expectedStatuses, resp.StatusCode, resp.Status)
  45. }
  46. body, err := ioutil.ReadAll(resp.Body)
  47. if err != nil {
  48. return fmt.Errorf("acme: error reading error body: %v", err)
  49. }
  50. acmeError := Problem{}
  51. if err := json.Unmarshal(body, &acmeError); err != nil {
  52. return fmt.Errorf("acme: parsing error body: %v - %s", err, string(body))
  53. }
  54. return acmeError
  55. }