rest.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package rest
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. )
  9. func getDetailedError(data []byte, err error) error {
  10. var limit int64 = 20
  11. syntaxError, ok := err.(*json.SyntaxError)
  12. if ok {
  13. start := syntaxError.Offset - 1
  14. if start < 0 {
  15. start = 0
  16. }
  17. end := start + limit
  18. dataLength := int64(len(data))
  19. if end > dataLength {
  20. end = dataLength
  21. }
  22. badPart := string(data[start:end])
  23. return fmt.Errorf("%s:\n%s", err.Error(), badPart)
  24. }
  25. typeError, ok := err.(*json.UnmarshalTypeError)
  26. if ok {
  27. start := typeError.Offset - limit
  28. if start < 0 {
  29. start = 0
  30. }
  31. badPart := string(data[start:typeError.Offset])
  32. return fmt.Errorf("%s:\n%s", err.Error(), badPart)
  33. }
  34. return err
  35. }
  36. //JSONDecoder decodes json from given bytes array to target object.
  37. func JSONDecoder(data []byte, target interface{}) error {
  38. err := json.Unmarshal(data, target)
  39. if err != nil {
  40. err = getDetailedError(data, err)
  41. }
  42. return err
  43. }
  44. //GET returns bytes buffer of response body.
  45. func GET(url string) (*bytes.Buffer, error) {
  46. resp, err := http.Get(url)
  47. if resp != nil {
  48. defer resp.Body.Close()
  49. }
  50. if err != nil {
  51. return nil, fmt.Errorf("Response error: %v", err)
  52. }
  53. body, err := BodyToBuffer(resp.Body)
  54. if err != nil {
  55. return nil, fmt.Errorf("Error reading body: %v", err)
  56. }
  57. if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent {
  58. return body, fmt.Errorf("Request unsuccessful: %v - %v", resp.Status, url)
  59. }
  60. return body, nil
  61. }
  62. //BodyToBuffer reads data from ReadCloser and returns bytes buffer.
  63. func BodyToBuffer(data io.ReadCloser) (*bytes.Buffer, error) {
  64. var buffer bytes.Buffer
  65. _, err := buffer.ReadFrom(data)
  66. if err != nil {
  67. return nil, err
  68. }
  69. return &buffer, nil
  70. }