How to say Hystrix not to trigger fallback for some of the exceptions in Hystrix command
Asked Answered
P

3

17

We were using the Hystrix functionality by directly extending the HystrixCommand class. But for some of the business exceptions, Hystrix's fallback method is being triggered.

I don't want to trigger the Hystrix fallback for some of the business specific exceptions. How I can achieve it without annotation based?

Policeman answered 29/5, 2017 at 16:37 Comment(0)
R
6

Use the ignoreExceptions annotation param

@HystrixCommand(ignoreExceptions = { BaseException.class, MissingServletRequestParameterException.class, TypeMismatchException.class })

See https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#error-propagation

I see you are extending the HystrixCommand instead of using the annotation, but that doesn't matter, just set that property in the command and it should have the same effect.

Unfortunately, a Hystrix Command is created by a Builder pattern, so you will have to do some hacking. The ignoreExceptions was added to DefaultProperties.java, which is used in the HystrixCommandBuilder

Radioactivity answered 29/5, 2017 at 16:53 Comment(2)
As per my understanding. Inside ignoreexceptions method of HystrixCommandBuilder, he is just copying the exceptions list. But as per the method comment I understood that these ignored exceptions can be wrapped in to Hystrixbadrequestexception. But can you let me know how to do that and also in a better way with a code snippetPoliceman
"just set that property in the command" - there is no such property in HystrixCommandTorr
H
2

If you wrap your logic in a try/catch and re-throw any exceptions in a HystrixBadRequestException then it will not trigger the fallback.

@Override
protected Object run() throws Exception {
    try {
        return //call goes here
    }
    catch (Throwable e) {
        //We wrap any exceptions in a HystrixBadRequestException because this way any other errors will not
        //trip the short circuit
        throw new HystrixBadRequestException("Exception thrown hystrix call", e);
    }
}

From the docs: http://netflix.github.io/Hystrix/javadoc/com/netflix/hystrix/exception/HystrixBadRequestException.html

An exception representing an error with provided arguments or state rather than an execution failure. Unlike all other exceptions thrown by a HystrixCommand this will not trigger fallback, not count against failure metrics and thus not trigger the circuit breaker.

NOTE: This should only be used when an error is due to user input such as IllegalArgumentException otherwise it defeats the purpose of fault-tolerance and fallback behavior.

Hulahula answered 17/11, 2017 at 20:35 Comment(0)
B
1

Two ways to do this.

  1. Using HystrixCommand annotation and specifying the exception types.

    @HystrixCommand(ignoreExceptions = { HttpStatusCodeException.class, JsonMappingException.class })
    
  2. Using "HystrixBadRequestException" and customize your code in way to just ignore few exception cases or status codes. This implementation will check for specific error codes on exceptions expected with you backend API contract and does not invoke hystrix fallback. Throwing "HystrixBadRequestException" will not count as hystrix fault.

    @HystrixCommand(commandKey = "MyHystrixCommand", fallbackMethod = "myHystrixFallback", threadPoolKey = "ThreadPoolKey")
    public ResponseEntity<String> getServiceCallResponse(String serviceUrl, HttpEntity<?> entity) {
    ResponseEntity<String> resp = null;
    try {
    resp = restTemplate.exchange(serviceUrl, HttpMethod.POST, entity, String.class)
            .getBody();
    }
    catch(Exception e) {
        handleExceptionForHystrix("getServiceCallResponse", e);
    }
    return resp;
    }
    
    private void handleExceptionForHystrix(String function, Exception e) {
            if (e instanceof HttpStatusCodeException) {
                HttpStatus httpStatusCode = ((HttpStatusCodeException)e).getStatusCode();
                if(httpStatusCode.equals(HttpStatus.BAD_REQUEST) || httpStatusCode.equals(HttpStatus.INTERNAL_SERVER_ERROR)) {
                    throw new HystrixBadRequestException("Hystrix Bad Request Exception Occurred" + httpStatusCode, e);
                }
                throw new RuntimeException(function, e);
            }
            throw new RuntimeException(function, e);
        }
    
    
    public ResponseEntity<String> myHystrixFallback(String serviceUrl, HttpEntity<?> entity, Throwable hystrixCommandExp) {
            return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    
Bush answered 25/2, 2019 at 16:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.