Commit 31f61d7d authored by Mitar's avatar Mitar
Browse files

Work with error-looking JSONs which are not errors.

parent 5f7dee67
Loading
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -208,7 +208,13 @@ func TestUnmarshalJSON(t *testing.T) {
	t.Parallel()

	//nolint:lll
	e, errE := errors.UnmarshalJSON([]byte(`{"error":"bulk indexing had failures","errors":[{"error":{"caused_by":{"reason":"Can't get text on a START_OBJECT at 1:106","type":"illegal_state_exception"},"reason":"failed to parse field [claims.rel.to] of type [keyword] in document with id 'SdQgTgtcqTm7xHV4PV1oAd'. Preview of field's value: '{id=SdQgTgtcqTm7xHV4PV1oAd}'","type":"mapper_parsing_exception"},"id":"SdQgTgtcqTm7xHV4PV1oAd"}],"seq":1,"stack":[{"file":"gitlab.com/peerdb/peerdb/internal/search/bridge.go","line":429,"name":"gitlab.com/peerdb/peerdb/internal/search.(*Bridge[...]).indexCommit"},{"file":"gitlab.com/peerdb/peerdb/internal/search/bridge.go","line":312,"name":"gitlab.com/peerdb/peerdb/internal/search.(*Bridge[...]).run"},{"file":"gitlab.com/peerdb/peerdb/internal/search/bridge.go","line":230,"name":"gitlab.com/peerdb/peerdb/internal/search.(*Bridge[...]).Start.func1"},{"file":"runtime/asm_amd64.s","line":1693,"name":"runtime.goexit"}],"view":"main"}`))
	data := `{"error":"bulk indexing had failures","errors":[{"error":{"caused_by":{"reason":"Can't get text on a START_OBJECT at 1:106","type":"illegal_state_exception"},"reason":"failed to parse field [claims.rel.to] of type [keyword] in document with id 'SdQgTgtcqTm7xHV4PV1oAd'. Preview of field's value: '{id=SdQgTgtcqTm7xHV4PV1oAd}'","type":"mapper_parsing_exception"},"id":"SdQgTgtcqTm7xHV4PV1oAd"}],"seq":1,"stack":[{"file":"gitlab.com/peerdb/peerdb/internal/search/bridge.go","line":429,"name":"gitlab.com/peerdb/peerdb/internal/search.(*Bridge[...]).indexCommit"},{"file":"gitlab.com/peerdb/peerdb/internal/search/bridge.go","line":312,"name":"gitlab.com/peerdb/peerdb/internal/search.(*Bridge[...]).run"},{"file":"gitlab.com/peerdb/peerdb/internal/search/bridge.go","line":230,"name":"gitlab.com/peerdb/peerdb/internal/search.(*Bridge[...]).Start.func1"},{"file":"runtime/asm_amd64.s","line":1693,"name":"runtime.goexit"}],"view":"main"}`

	e, errE := errors.UnmarshalJSON([]byte(data))
	require.NoError(t, errE, "% -+#.1v", errE)
	assert.EqualError(t, e, "bulk indexing had failures")

	jsonError, err := json.Marshal(errors.Formatter{Error: e})
	require.NoError(t, err)
	jsonEqual(t, data, string(jsonError))
}
+29 −29
Original line number Diff line number Diff line
@@ -52,9 +52,8 @@ func UnmarshalJSON(data []byte) (error, E) { //nolint:revive,staticcheck
	if ok {
		err := json.Unmarshal(errorData, &msg)
		if err != nil {
			errE := WithMessage(err, "error") //nolint:govet
			Details(errE)["json"] = string(errorData)
			return nil, errE
			// "error" field is not a string, treat it as a detail.
			payload["error"] = errorData
		}
	}

@@ -63,11 +62,10 @@ func UnmarshalJSON(data []byte) (error, E) { //nolint:revive,staticcheck
	if ok {
		err := json.Unmarshal(stackData, &s)
		if err != nil {
			errE := WithMessage(err, "stack") //nolint:govet
			Details(errE)["json"] = string(stackData)
			return nil, errE
		}
		if len(s) == 0 {
			// "stack" field is not a stack trace, treat it as a detail.
			payload["stack"] = stackData
			s = nil
		} else if len(s) == 0 {
			s = nil
		}
	}
@@ -77,9 +75,9 @@ func UnmarshalJSON(data []byte) (error, E) { //nolint:revive,staticcheck
	if ok {
		cause, errE = UnmarshalJSON(causeData)
		if errE != nil {
			errE := WithMessage(errE, "cause") //nolint:govet
			Details(errE)["json"] = string(causeData)
			return nil, errE
			// "cause" field is not an error, treat it as a detail.
			payload["cause"] = causeData
			cause = nil
		}
	}

@@ -89,16 +87,17 @@ func UnmarshalJSON(data []byte) (error, E) { //nolint:revive,staticcheck
		var errorsSliceData []json.RawMessage
		err := json.Unmarshal(errorsData, &errorsSliceData)
		if err != nil {
			errE := WithMessage(err, "errors")
			Details(errE)["json"] = string(errorsData)
			return nil, errE
		}
		for i, d := range errorsSliceData {
			// "errors" field is not a slice, treat it as a detail.
			payload["errors"] = errorsData
			errs = nil
		} else {
			for _, d := range errorsSliceData {
				e, errE := UnmarshalJSON(d)
				if errE != nil {
				errE := WithMessagef(errE, "errors: %d", i) //nolint:govet
				Details(errE)["json"] = string(d)
				return nil, errE
					// "errors" field is not a slice of errors, treat it as a detail.
					payload["errors"] = errorsData
					errs = nil
					break
				}
				if e != nil {
					// If e is equal to cause, we want to have e be the same pointer to cause, so that
@@ -110,6 +109,7 @@ func UnmarshalJSON(data []byte) (error, E) { //nolint:revive,staticcheck
					}
				}
			}
		}
		if len(errs) == 0 {
			errs = nil
		}