Browse Source

Getting affected part of json with the error

Piotr Czajkowski 3 years ago
parent
commit
e99e5331d6
2 changed files with 32 additions and 134 deletions
  1. 32 0
      rest.go
  2. 0 134
      rest_test.go

+ 32 - 0
rest.go

@@ -8,9 +8,41 @@ import (
 	"net/http"
 )
 
+func getDetailedError(data []byte, err error) error {
+	var limit int64 = 20
+
+	syntaxError, ok := err.(*json.SyntaxError)
+	if ok {
+		end := syntaxError.Offset - 1 + limit
+		dataLength := int64(len(data))
+		if end > dataLength {
+			end = dataLength
+		}
+
+		badPart := string(data[syntaxError.Offset-1 : end])
+		return fmt.Errorf("%s:\n%s", err.Error(), badPart)
+	}
+
+	typeError, ok := err.(*json.UnmarshalTypeError)
+	if ok {
+		start := typeError.Offset - limit
+		if start < 0 {
+			start = 0
+		}
+
+		badPart := string(data[start:typeError.Offset])
+		return fmt.Errorf("%s:\n%s", err.Error(), badPart)
+	}
+
+	return err
+}
+
 //JSONDecoder decodes json from given bytes array to target object.
 func JSONDecoder(data []byte, target interface{}) error {
 	err := json.Unmarshal(data, target)
+	if err != nil {
+		err = getDetailedError(data, err)
+	}
 
 	return err
 }

+ 0 - 134
rest_test.go

@@ -1,134 +0,0 @@
-package rest
-
-import (
-	"bytes"
-	"fmt"
-	"net/http"
-	"net/http/httptest"
-	"testing"
-
-	"github.com/go-test/deep"
-)
-
-type Something struct {
-	First  int
-	Second string
-}
-
-func TestJSONDecoder(t *testing.T) {
-	const json = `{ "First": 15, "Second": "Some string" }`
-	buffer := bytes.NewBuffer([]byte(json))
-
-	expected := Something{First: 15, Second: "Some string"}
-
-	var result Something
-	err := JSONDecoder(buffer.Bytes(), &result)
-	if err != nil {
-		t.Error(err)
-	}
-
-	if diff := deep.Equal(expected, result); diff != nil {
-		t.Errorf("Wrong result: %v", diff)
-	}
-}
-
-func TestJSONDecoderBadJSON(t *testing.T) {
-	const badJSON = `{ First: 15, "Second": "Some string" }`
-	buffer := bytes.NewBuffer([]byte(badJSON))
-
-	expected := Something{First: 15, Second: "Some string"}
-
-	var result Something
-	err := JSONDecoder(buffer.Bytes(), &result)
-	if err == nil {
-		t.Error("There should be an error")
-	}
-
-	if diff := deep.Equal(expected, result); diff == nil {
-		t.Error("Structures shouldn't match")
-	}
-}
-
-func fakeServer(statusCode int, data string) *httptest.Server {
-	function := func(w http.ResponseWriter, r *http.Request) {
-		w.WriteHeader(statusCode)
-		w.Header().Set("Content-Type", "text")
-		fmt.Fprint(w, data)
-	}
-
-	return httptest.NewServer(http.HandlerFunc(function))
-}
-
-func TestGET(t *testing.T) {
-	expected := "Some text"
-	server := fakeServer(http.StatusOK, expected)
-	defer server.Close()
-
-	data, err := GET(server.URL)
-	if data == nil {
-		t.Error("Data shouldn't be nil")
-	}
-
-	if err != nil {
-		t.Error(err)
-	}
-
-	result := data.String()
-
-	if expected != result {
-		t.Errorf("Wrong result, %v", result)
-	}
-}
-
-func TestGET206(t *testing.T) {
-	expected := "Some text"
-	server := fakeServer(http.StatusPartialContent, expected)
-	defer server.Close()
-
-	data, err := GET(server.URL)
-	if data == nil {
-		t.Error("Data shouldn't be nil")
-	}
-
-	if err != nil {
-		t.Error(err)
-	}
-
-	result := data.String()
-
-	if expected != result {
-		t.Errorf("Wrong result, %v", result)
-	}
-}
-
-func TestGET404(t *testing.T) {
-	expected := "Some text"
-	server := fakeServer(http.StatusNotFound, expected)
-	defer server.Close()
-
-	data, err := GET(server.URL)
-	if data == nil {
-		t.Error("Data shouldn't be nil")
-	}
-
-	if err == nil {
-		t.Error("There should be an error!")
-	}
-
-	result := data.String()
-
-	if expected != result {
-		t.Errorf("Wrong result, %v", result)
-	}
-}
-
-func TestGETNoServer(t *testing.T) {
-	data, err := GET("/")
-	if data != nil {
-		t.Error("Data should be nil!")
-	}
-
-	if err == nil {
-		t.Error("There should be an error!")
-	}
-}