How to get the client response?
GaoJianAllen opened this issue · comments
I received an error response from the client side.
I try to parse the response from runtime.APIError.
However, the type of Response is interface and deeper type is client.response.
It is lowercase and private.
So how to get the response? I just want to get http.Response.
https://github.com/go-openapi/runtime/blob/master/client_response.go#L59
https://github.com/go-openapi/runtime/blob/master/client/response.go#L29
You can access some fields of http.Response
via these methods:
Lines 32 to 50 in da56347
Would you like to access something else?
You can access some fields of
http.Response
via these methods:Lines 32 to 50 in da56347
Would you like to access something else?
Thank you for replying. I try to use below code to get response.
`
if apiErr, ok := err.(*runtime.APIError); ok {
if resp, ok := apiErr.Response.(interface{ Body() io.ReadCloser }); ok {
body := resp.Body()
bs, ee := io.ReadAll(body)
if ee != nil {
return ee
}
fmt.Printf(string(bs))
}
}
`
However, the io.ReadCloser is closed so that I can't read the original message.
So it doesn't resolve my scenario.
My case is thatm the service doesn't define an error(e.g. 401) in yaml spec. So I can't read the body of the request to parse the message. If I use go-swagger framework, it will lose the message
How about using a client option to intercept the response? For example, define these functions:
func errorHandler(r runtime.ClientResponseReader) runtime.ClientResponseReaderFunc {
return func(res runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if res.Code() >= 400 {
return nil, runtime.NewAPIError(res.Message(), res, res.Code())
}
return r.ReadResponse(res, consumer)
}
}
func withErrorHandler(req *runtime.ClientOperation) {
req.Reader = errorHandler(req.Reader)
}
And use withErrorHandler
when calling an API like this:
res, err := client.Default.Operations.GetSomething(operations.GetSomethingParams(), withErrorHandler)
Then the returned runtime.APIError
should have an io.ReadCloser
that is not consumed yet.
You can also read the body inside errorHandler
like this:
func errorHandler(r runtime.ClientResponseReader) runtime.ClientResponseReaderFunc {
return func(res runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if res.Code() >= 400 {
//TODO: read `res.Body()` and return an appropriate error.
}
return r.ReadResponse(res, consumer)
}
}
It'll save you from casting errors.
@jkawamoto That resolves my problem. Thank you a lot!