-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Cleaner error propagation in hystrix core. #1379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Maybe this feature should be optional and activated by property for backward compatibility. |
|
I agree and was going to suggest that this feature should be Optional as it is not required for every use case using Hystrix. |
|
Please take a look at code changes if fix is applied in the right place. Then I will continue with implementation, tests and docs. |
|
Will take a look in some time. |
|
I understand the desire for this feature, but after reviewing it, I'm not convinced it belongs in Thoughts? |
|
-1 to this change being the new default. It would have to user enabled since it would be non-passively altering behavior. The zuul[1] route filter is expecting the exception to be [1] https://github.com/Netflix/zuul/blob/zuul-1.0.28/zuul-netflix-webapp/src/main/groovy/filters/route/ZuulNFRequest.groovy#L151 |
|
@mattrjacobs, @mattnelson thanks for your thoughts. I agree that it can't be a default. I will try with |
|
I'm not sure if it's possible with HystrixPlugins. I tried to do this in following way. public class MyHystrixCommandExecutionHook extends HystrixCommandExecutionHook {
private static MyHystrixCommandExecutionHook INSTANCE = new MyHystrixCommandExecutionHook();
private MyHystrixCommandExecutionHook() {
}
public static MyHystrixCommandExecutionHook getInstance() {
return INSTANCE;
}
@Override
public <T> Exception onError(HystrixInvokable<T> commandInstance, FailureType failureType, Exception e) {
System.out.println("onError");
e.printStackTrace();
return new Exception("My exception 2");
}
}Note that in onError() method I replaced oryginal exception by exception with message: "My exception 2". public class CommandHelloWorld extends HystrixCommand<String> {
public CommandHelloWorld() {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
}
@Override
protected String run() throws Exception {
throw new Exception("My exception");
}
}Now the command has to be executed: Hystrix.reset();
HystrixPlugins.reset();
HystrixPlugins.getInstance().registerCommandExecutionHook(MyHystrixCommandExecutionHook.getInstance());
new CommandHelloWorld().execute(); First it's invoked onError() method. So stack trace of the oryginal exception is printed. public R execute() {
try {
return queue().get();
} catch (Exception e) {
throw decomposeException(e);
}
}Let's see qeue() method: public Future<R> queue() {
final Observable<R> o = toObservable();
final Future<R> f = o.toBlocking().toFuture();
if (f.isDone()) {
try {
f.get();
return f;
} catch (Exception e) {
RuntimeException re = decomposeException(e);
if (re instanceof HystrixBadRequestException) {
return f;
} else if (re instanceof HystrixRuntimeException) {
HystrixRuntimeException hre = (HystrixRuntimeException) re;
if (hre.getFailureType() == FailureType.COMMAND_EXCEPTION || hre.getFailureType() == FailureType.TIMEOUT) {
// we don't throw these types from queue() only from queue().get() as they are execution errors
return f;
} else {
// these are errors we throw from queue() as they as rejection type errors
throw hre;
}
} else {
throw re;
}
}
}
return f;
}I checked that onError() is used somewhere in toObservable() method, so decomposeException() is invoked after this and, as you can see, there is nothing that is called after decomposeException(). |
|
@tjuchniewicz Have you seen the work in #1414? That looks like a way forward where users mark specific exceptions as not wanting wrapping. Since it is opt-in, it doesn't affect any existing code but makes this functionality available. Would love your thoughts on it |
|
@mattrjacobs Looks good for me. Thanks! |
Fixes gh-1366.