0

I am using gin framework to built an Api to get data from Elastic. Issue is that when I run the application, I get response successfully in the first request but after that in any subsequent request I am getting error:

Error parsing the response body: EOF 

Elastic configuration:

var cfg = elasticsearch.Config{ Password: GetConnectConfig().esPassword, Username: GetConnectConfig().esUserName, Addresses: GetConnectConfig().esHost, Logger: &estransport.ColorLogger{ Output: os.Stdout, } 

My request handler function looks like:

func Search() gin.HandlerFunc { client, err := elasticsearch.NewClient(cfg) if err != nil { log.Fatalf("elastic configuration failed %s", err) } res, err := client.Search( client.Search.WithIndex(Index_Name), client.Search.WithSize(10), client.Search.WithPretty(), ) if err != nil { log.Fatalf("elastic failed to respond %s", err) } return func(c *gin.Context) { r := map[string]interface{}{} if err := json.NewDecoder(res.Body).Decode(&r); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err}) log.Fatalf("Error parsing the response body: %s", err) // Error } else { for _, hit := range r["hits"].(map[string]interface{})["hits"].([]interface{}) { log.Printf(" * ID=%s, %s", hit.(map[string]interface{})["_id"], hit.(map[string]interface{})["_source"]) } c.JSON(http.StatusOK, "success") } } } 

As I told, I am able to get the response only in the very first request each time I run the application. I am not sure what is the cause of error here.

I also tried with closing the response body after search by adding:

defer res.Body.Close() 

but now I am getting following error:

Error parsing the response body: http2: response body closed 
3
  • i guess your defer res.Body.Close() should be inside the func(c *gin.Context){} as your first statement, your handler is returning a function which will execute at a later time you cannot close body inside your handler.. or move your search initialization inside the func and do a close inside there Commented Feb 8, 2021 at 11:02
  • it is better to initialize your elastic search client in your main.go or in your app bootsrap and pass it as a dependency to your handler Commented Feb 8, 2021 at 11:06
  • I figured out the issue, It was coming from the same place as you pointed. After initializing the client in main function and executing elastic search query inside func(c *gin.Context){}, I am able to get the results. Thank you for your quick reply. Can you please post the solution here? or if you want I will post it. Commented Feb 8, 2021 at 12:58

1 Answer 1

1

defer res.Body.Close() should be inside the func(c *gin.Context){} yo. can move your search initialization inside the func and do a close inside there something like and client can be injected as a dependency here.

 return func(c *gin.Context) { res, err := client.Search( client.Search.WithIndex(Index_Name), client.Search.WithSize(10), client.Search.WithPretty(), ) defer res.Body.Close() } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.