From 2266bb91e932872e02fd789f82987941117ffe35 Mon Sep 17 00:00:00 2001 From: Sai Kiran <85323324+r00tu53r@users.noreply.github.com> Date: Wed, 8 Dec 2021 12:20:24 +1100 Subject: [PATCH 1/2] Report error root cause if available --- internal/elasticsearch/error.go | 61 ++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/internal/elasticsearch/error.go b/internal/elasticsearch/error.go index 0a1bdf160b..f665d6ca4f 100644 --- a/internal/elasticsearch/error.go +++ b/internal/elasticsearch/error.go @@ -13,19 +13,64 @@ import ( // NewError returns a new error constructed from the given response body. // This assumes the body contains a JSON encoded error. If the body cannot // be parsed then an error is returned that contains the raw body. -func NewError(body []byte) error { - type ErrorBody struct { - Error struct { - Type string `json:"type"` - Reason string `json:"reason"` - } `json:"error"` - } +type ErrorBody struct { + Error struct { + RootCause []struct { + Type string `json:"type"` + Reason string `json:"reason"` + ProcessorType string `json:"processor_type"` + ScriptStack []string `json:"script_stack"` + Script string `json:"script"` + Lang string `json:"lang"` + Position struct { + Offset int `json:"offset"` + Start int `json:"start"` + End int `json:"end"` + } `json:"position"` + Suppressed []struct { + Type string `json:"type"` + Reason string `json:"reason"` + ProcessorType string `json:"processor_type"` + } `json:"suppressed"` + } `json:"root_cause"` + Type string `json:"type"` + Reason string `json:"reason"` + ProcessorType string `json:"processor_type"` + ScriptStack []string `json:"script_stack"` + Script string `json:"script"` + Lang string `json:"lang"` + Position struct { + Offset int `json:"offset"` + Start int `json:"start"` + End int `json:"end"` + } `json:"position"` + CausedBy struct { + Type string `json:"type"` + Reason string `json:"reason"` + CausedBy struct { + Type string `json:"type"` + Reason interface{} `json:"reason"` + } `json:"caused_by"` + } `json:"caused_by"` + Suppressed []struct { + Type string `json:"type"` + Reason string `json:"reason"` + ProcessorType string `json:"processor_type"` + } `json:"suppressed"` + } `json:"error"` + Status int `json:"status"` +} +func NewError(body []byte) error { var errBody ErrorBody if err := json.NewDecoder(bytes.NewReader(body)).Decode(&errBody); err == nil { + if len(errBody.Error.RootCause) > 0 { + rootCause, _ := json.MarshalIndent(errBody.Error.RootCause, "", " ") + return fmt.Errorf("elasticsearch error (type=%v): %v\nRoot cause:\n%v", errBody.Error.Type, + errBody.Error.Reason, string(rootCause)) + } return fmt.Errorf("elasticsearch error (type=%v): %v", errBody.Error.Type, errBody.Error.Reason) } - // Fall back to including to raw body if it cannot be parsed. return fmt.Errorf("elasticsearch error: %v", string(body)) } From 9d5c22a2868511ac5ec0d303b2961391293b7629 Mon Sep 17 00:00:00 2001 From: Sai Kiran <85323324+r00tu53r@users.noreply.github.com> Date: Wed, 8 Dec 2021 13:28:13 +1100 Subject: [PATCH 2/2] Add omitempty to ErrorBody fields and update test --- internal/elasticsearch/error.go | 30 ++++++++++++++-------------- internal/elasticsearch/error_test.go | 16 ++++++++++++++- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/internal/elasticsearch/error.go b/internal/elasticsearch/error.go index f665d6ca4f..fb717f300b 100644 --- a/internal/elasticsearch/error.go +++ b/internal/elasticsearch/error.go @@ -18,45 +18,45 @@ type ErrorBody struct { RootCause []struct { Type string `json:"type"` Reason string `json:"reason"` - ProcessorType string `json:"processor_type"` - ScriptStack []string `json:"script_stack"` - Script string `json:"script"` - Lang string `json:"lang"` + ProcessorType string `json:"processor_type,omitempty"` + ScriptStack []string `json:"script_stack,omitempty"` + Script string `json:"script,omitempty"` + Lang string `json:"lang,omitempty"` Position struct { Offset int `json:"offset"` Start int `json:"start"` End int `json:"end"` - } `json:"position"` + } `json:"position,omitempty"` Suppressed []struct { Type string `json:"type"` Reason string `json:"reason"` ProcessorType string `json:"processor_type"` - } `json:"suppressed"` - } `json:"root_cause"` + } `json:"suppressed,omitempty"` + } `json:"root_cause,omitempty"` Type string `json:"type"` Reason string `json:"reason"` - ProcessorType string `json:"processor_type"` - ScriptStack []string `json:"script_stack"` - Script string `json:"script"` - Lang string `json:"lang"` + ProcessorType string `json:"processor_type,omitempty"` + ScriptStack []string `json:"script_stack,omitempty"` + Script string `json:"script,omitempty"` + Lang string `json:"lang,omitempty"` Position struct { Offset int `json:"offset"` Start int `json:"start"` End int `json:"end"` - } `json:"position"` + } `json:"position,omitempty"` CausedBy struct { Type string `json:"type"` Reason string `json:"reason"` CausedBy struct { Type string `json:"type"` Reason interface{} `json:"reason"` - } `json:"caused_by"` - } `json:"caused_by"` + } `json:"caused_by,omitempty"` + } `json:"caused_by,omitempty"` Suppressed []struct { Type string `json:"type"` Reason string `json:"reason"` ProcessorType string `json:"processor_type"` - } `json:"suppressed"` + } `json:"suppressed,omitempty"` } `json:"error"` Status int `json:"status"` } diff --git a/internal/elasticsearch/error_test.go b/internal/elasticsearch/error_test.go index a9c4a94d4b..0f248ef3fb 100644 --- a/internal/elasticsearch/error_test.go +++ b/internal/elasticsearch/error_test.go @@ -29,6 +29,20 @@ func TestNewError(t *testing.T) { "status" : 400 }` + const expected = `elasticsearch error (type=parse_exception): processor [set] doesn't support one or more provided configuration parameters [fail] +Root cause: +[ + { + "type": "parse_exception", + "reason": "processor [set] doesn't support one or more provided configuration parameters [fail]", + "processor_type": "set", + "position": { + "offset": 0, + "start": 0, + "end": 0 + } + } +]` err := elasticsearch.NewError([]byte(resp)) - assert.Equal(t, err.Error(), "elasticsearch error (type=parse_exception): processor [set] doesn't support one or more provided configuration parameters [fail]") + assert.Equal(t, err.Error(), expected) }