How to handle 4xx errors in Golang Hystrix circuit breaker

325 Views Asked by At

While writing a circuit breaker, I am making an api call to upstream service, which will either give 5xx or 4xx errors. I want to consider only 5xx errors for opening the circuit while 4xx should be handled normally.

        resp, err := clients.DoHTTPCall(url, "POST", payload, ConnectionTimeOut, []string{config.Config.ContactConfig.AuthTokenHeaderNameInLoadRequest}, []string{authToken})
        logging.Info("test", "%v", *resp)
        if err != nil {
            common.TrackStats(common.CurrencyToCountryMap[currencyCode], userType, LOAD_CONTACT_DATA_API, common.API_ERROR)
            //logging.Error(logtag, "Error on loadContactLoadData request=%v err=%v contactLoadApiMsgId=%v", request, err, contactLoadApiMsgId)
            return responses.NewError(responses.InternalServerError, err.Error())
        }
        return nil
    }, circuitbreaker.WithFallback(contactLoadFallback()))```
2

There are 2 best solutions below

0
SaharatT On

Just return error only when it is 5xx. Hystrix will accumulate the error returned from function to check if the circuit should be opened. You can still use StatusCode in resp to handle each status code separately.

0
rs_ On
hystrix.Go(config.Config.CircuitSetting.ContactCircuitName, func() error {
        resp, err := clients.DoHTTPCall(url, "GET", payload, ConnectionTimeOut, []string{config.Config.ContactConfig.AuthTokenHeaderNameInLoadRequest}, authToken)
        if resp != nil {
            response = *resp
        }
        if err != nil {
            logging.Error(logtag, "Error on request=%v err=%v", request, err)
            return err
        } else if resp.StatusCode >= 500 {
            return err //send circuitnbreaker error
        }
        return nil
    }, func(err error) error {
        //fallabck function
        circuit, _, _ := 
        hystrix.GetCircuit(config.Config.CircuitSetting.ContactCircuitName)
        logging.Info(logtag, "Is circuit Open: %v", circuit.IsOpen())
        return err
    })