Handle invalid json returned from backend
This commit is contained in:
parent
5da3972d73
commit
e7e73947bd
@ -694,6 +694,25 @@ func (b *BitcoinRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error)
|
|||||||
return res.Result, nil
|
return res.Result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func safeDecodeResponse(body io.ReadCloser, res interface{}) (err error) {
|
||||||
|
var data []byte
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
glog.Error("unmarshal json recovered from panic: ", r, "; data: ", string(data))
|
||||||
|
if len(data) > 0 && len(data) < 2048 {
|
||||||
|
err = errors.Errorf("Error: ", string(data))
|
||||||
|
} else {
|
||||||
|
err = errors.New("Internal error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
data, err = ioutil.ReadAll(body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return json.Unmarshal(data, &res)
|
||||||
|
}
|
||||||
|
|
||||||
func (b *BitcoinRPC) Call(req interface{}, res interface{}) error {
|
func (b *BitcoinRPC) Call(req interface{}, res interface{}) error {
|
||||||
httpData, err := b.RPCMarshaler.Marshal(req)
|
httpData, err := b.RPCMarshaler.Marshal(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -713,19 +732,16 @@ func (b *BitcoinRPC) Call(req interface{}, res interface{}) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// read the entire response body until the end to avoid memory leak when reusing http connection
|
|
||||||
// see http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/
|
|
||||||
defer io.Copy(ioutil.Discard, httpRes.Body)
|
|
||||||
// if server returns HTTP error code it might not return json with response
|
// if server returns HTTP error code it might not return json with response
|
||||||
// handle both cases
|
// handle both cases
|
||||||
if httpRes.StatusCode != 200 {
|
if httpRes.StatusCode != 200 {
|
||||||
err = json.NewDecoder(httpRes.Body).Decode(&res)
|
err = safeDecodeResponse(httpRes.Body, &res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New(httpRes.Status)
|
return errors.Errorf("%v %v", httpRes.Status, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return json.NewDecoder(httpRes.Body).Decode(&res)
|
return safeDecodeResponse(httpRes.Body, &res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetChainParser returns BlockChainParser
|
// GetChainParser returns BlockChainParser
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user