Http client read 400 response body

Hey, Do you know how can I access to the last buffer value of this http response:

I tried errBody, errReadBody := ioutil.ReadAll(resp.Body) but it’s empty :frowning:

I also tried:

dump, err := httputil.DumpResponse(resp, true)
		fmt.Printf("%q", dump)

When I debug on breakpoint I can get:

HTTP/1.1 400 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 16 Dec 2021 21:52:32 GMT
Connection: close

38d
{"timestamp":1639691552111,"status":400,"error":"Bad Request","exception":"org.springframework.http.converter.HttpMessageNotReadableException","message":"JSON parse error: Unrecognized field \"geoCriteria\" (class google.ads.controllers.PostCampaignController$Campaign), not marked as ignorable; nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field \"geoCriteria\" (class google.ads.controllers.PostCampaignController$Campaign), not marked as ignorable (8 known properties: \"status\", \"urls\", \"budget\", \"biddingStrategyType\", \"getGeoCriteria\", \"end\", \"start\", \"languagesCriteria\"])\n at [Source: (PushbackInputStream); line: 1, column: 64] (through reference chain: google.ads.controllers.PostCampaignController$PostCampaignBody[\"campaign\"]->google.ads.controllers.PostCampaignController$Campaign[\"geoCriteria\"])","path":"/post/campaign"}

I can’t tell from your screenshot what the problem is. Do you have some sample code you wrote that isn’t doing what you expect and that you could share?

I have requested my server that return a HTTP 400 with an error code inside the response body.

I can see the error on Goland IDE debugguer, bu I want to treat it, I need to be able to read it as a string to regexp it… And I’m not able to get the content using Go http Response.

not have http request info. if status is 400 then request object invliad.

What exactly is empty?

When you say errBody is empty, how have you checked? At the same time, what is the value of errReadBody?

Can you please show more code about how you do the request, and inspect its response?

This is my query:

googleAPICreateCampaignJSON, err := json.Marshal(googleAPICreateCampaign)
	if apitools.SetWrappedErrorAndNotify(&w, "Error during writing google request", err) {
		return true
	}
	bufferParams := bytes.NewBuffer(googleAPICreateCampaignJSON)

	req, err := http.NewRequest("POST", BASE_URL+"/post/campaign", bufferParams)
	if apitools.SetWrappedErrorAndNotify(&w, "Error during writing google request", err) {
		return true
	}
	req.Header.Set("Content-Type", "application/json")
	curl, _ := http2curl.GetCurlCommand(req)
	googleResp, err := http.DefaultClient.Do(req)
	if apitools.SetWrappedErrorAndNotify(&w, "Error during google call", err) {
		return true
	}
var data struct {
		ID string `json:"id"`
	}
	dec := json.NewDecoder(googleResp.Body)
	err = dec.Decode(&data)
        // get error body here
	if apitools.SetWrappedStatusAndNotify(w, "Error during oauth validation", *curl, *req, googleResp) {
		return true
	}

This finaly found a solution my mistake was to try to read the body content to get the error a second time… After that buffer is empty and the error is only on the body r buffer that I can’t read. THe solution that worked:

req, err := http.NewRequest("POST", BASE_URL+"/post/campaign", body)
	if apitools.SetWrappedErrorAndNotify(&w, "Error during writing google request", err) {
		return true
	}
	req.Header.Set("Content-Type", "application/json")
	curl, _ := http2curl.GetCurlCommand(req)
	googleResp, err := http.DefaultClient.Do(req)
	if apitools.SetWrappedErrorAndNotify(&w, "Error during google call", err) {
		return true
	}
	if apitools.SetWrappedStatusAndNotify(w, "Error during oauth validation", *curl, *req, googleResp) {
		return true
	}
	var data struct {
		ID string `json:"id"`
	}
	dec := json.NewDecoder(googleResp.Body)
	err = dec.Decode(&data)

This is how I try to read the error body:

func SetWrappedStatusAndNotify(w http.ResponseWriter, msg string, curl http2curl.CurlCommand, req http.Request, resp *http.Response) bool {
	if resp.StatusCode != http.StatusOK {
		headers := ""
		if reqHeadersBytes, err := json.Marshal(resp.Request.Header); err != nil {
			headers = "Could not Marshal Req Headers"
		} else {
			headers = string(reqHeadersBytes)
		}
		errBody, errReadBody := ioutil.ReadAll(resp.Body)
		if errReadBody != nil {
			logs.Log.Errorf("%v+", errReadBody)
		}
		dump, err := httputil.DumpResponse(resp, true)
		fmt.Printf("%s", dump)
		if err != nil {
			log.Fatal(err)
		}

		detailMessage := fmt.Sprintf(`
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Unable to query: %v 
--------------------------------------------------------------------------------------------------------------------------------------------------------------
Request %s: %s

Request (curl) %s

Response: %v

Error: %v

Headers: %s

ResponseError: %s
--------------------------------------------------------------------------------------------------------------------------------------------------------------
`,
			resp.Request.URL.RequestURI(),
			req.URL.RequestURI(),
			formater.FormatRequest(&req),
			curl,
			resp,
			err,
			headers,
			errBody,
		)
		safeError := errors.BadRequest.NewWithDetails("Bad status "+resp.Status, detailMessage)
		ReplySafeError(&w, safeError, safeError)
		return true
	} else {
		return false
	}
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.