Is it possible to selectively ignore service exception in Hystrix? - hystrix

I have client API jar which internally makes external calls and throws single generic Service exception in case of issues. I have written hystrix wrapper over the API calls. There are cases like "user not found" returning exception. Though the call was successful and service responded with valid response, the hystrix is treating it as a failure. I know that we can ignore the exception in Hystrix; but it will whitelist the only exception thrown by service calls. Is there a way to selectively ignore exception thrown by the service calls based on message in exception or http status code or something?

If the external service throw different exceptions in different cases, then you can probably ignore those exceptions like this
#HystrixCommand(ignoreExceptions = {SomeException.class})
But if you have to ignore exceptions bases on error message then the best way to tackle this is put a try catch around your external call. And in the catch block check if it is one of those exceptions which needs to be ignored. If so don't do anything. If not rethrow this exception. Something like this will do. More info about HystrixBadRequestException
#HystrixCommand(fallbackMethod = "fallBackMethod", groupKey = "CircuitBreaker", commandKey = "somekey", threadPoolKey = "somekey",
commandProperties = {
#HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "10000"),
#HystrixProperty(name = "execution.timeout.enabled", value = "false"),
#HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
#HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "1200000"),
},
threadPoolProperties = {
#HystrixProperty(name = "coreSize", value = "30"),
#HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "180000")
})
public void someMethod(....){
try {
// Call external service
} catch(Exception e) {
if(exception to be ignored)
throw new HystrixBadRequestException("Some message", e);
else
throw e
}
}

Related

How to interrupt JoinPoint execution in AOP

Is it possible to interrupt invoking the actual method from within the aspect execution?
For example:
public class CheckPermissionAspect {
#Around("#annotation(CheckPermission)")
public Object methodLogging( ProceedingJoinPoint joinPoint) throws Throwable {
// before method execution
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
log.info("Enter ==> " + signature.getMethod().getName());
if ( getPermission( principal.getName()) == false ) {
// break the execution of actual method
Object result = null; // ???
log.info("Break ==> " + signature.getMethod().getName());
} else {
// invoke the actual method
Object result = joinPoint.proceed();
// after method execution
log.debug("Result: " + result);
log.info("Leave ==> " + signature.getMethod().getName());
}
return result;
}
}
To set Object result = null; does not work.
Thank you for any help.
From Spring Reference documentation : Around Advice
Within the body of the advice method, you must invoke proceed() on the
ProceedingJoinPoint in order for the underlying method to run
If joinPoint.proceed() is removed from the code or an exception is thrown before joinPoint.proceed() statement or a return is issued before joinPoint.proceed() statement , the execution of the underlying method would get interrupted.
Update : to answer the comment
Spring AOP is proxy based. To understand this concept better , do read through : Understanding AOP proxies
An advice is placed between the calling method and the target. All calls to the target method gets intercepted and advised.
You could throw an exception upon validation ( Do note that the exception type thrown should match the exception type of the target method . Go through this Q&A).
The exception/return value from the advise would reach back the calling method .

Weird Angular exception: [$rootScope:inprog] null already in progress

I get a very strange exception with AngularJS 1.5.9
[$rootScope:inprog] null already in progress
Here is the source code where this exception is thrown:
function beginPhase(phase) {
if ($rootScope.$$phase) {
throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase);
}
$rootScope.$$phase = phase;
}
beginPhase() is called with "$apply" or "$digest".
My question is:
How is it possible to enter the "if" while $rootScope.$$phase is null?
Any help will be appreciated.
To answer your question $rootScope.$$phase can be set to "null" (string) which will result in this error being thrown.
I'm not sure how you were able to capture this message but Sentry reports that for me and I'm getting a ton of those exceptions from just a bunch of users.
So in order to reduce the spam I made a function which will remove the stack from the exception, and will clear the $rootScope.$$phase which will hopefully prevent a second occurrence:
function exceptionHandler(){
const error = Error;
const nullMessage = "[$rootScope:inprog] null already in progress";
function exception(message){
if(message.indexOf(nullMessage) === 0){
const $rootScope = exceptionHandler.$rootScope;
if($rootScope) $rootScope.$$phase = null;
const exception = new error(nullMessage);
exception.stack = "";
return exception;
}
return new error(message);
}
Error = exception;
}
exceptionHandler(); // If it's not run AngularJS will use the original Error constructor, the one we're decorating
And then in angular.run inject $rootScope and set it as a property of the function:
angular.run(["$rootScope", function($rootScope){
exceptionHandler.$rootScope = $rootScope;
}]);
My assumption was that an extension was setting $rootScope.$$phase to "null" but after installing the same extensions as one of my users the exception did not occur.
Star on GistHub

How to properly call rtlunwind from within an x86_64 windows exception handler

I'm trying to implement a win64 exception personality and can't find much documentation on the subject.
I've already got a working win32 version but the win64 one crashes on rtlunwind (access violation) in the "catch" part of a win64 exception handler, to unwind to the catch handler frame and continuation:
int ExceptionHandler(EXCEPTION_RECORD arec, uint64_t EstablisherFrame, PCONTEXT context, PDISPATCHER_CONTEXT dispatcher)
{
if (0 == (arec->ExceptionFlags & ( rtl.EXCEPTION_UNWINDING | rtl.EXCEPTION_EXIT_UNWIND)))
{
// check if this is a catch supported
rtl.RtlUnwindEx(EstablisherFrame, NULL, arec, NULL, context, dispatcher->HistoryTable);
// call catch & jump to continuation
}
}
Basically, I'm trying to find the parameters to RtlUnwind/RtlUnwindEx for a given catch.
Can anyone point me to information on what I can try or a sample implementation of seh for win64?
turns out this can be done by passing a new exception object to rtlUnwind with a CallCatch method as first info parameter, with STATUS_UNWIND_CONSOLIDATE as code. This will unwind the whole thing (retriggering the personality for any cleanup/finally)
EXCEPTION_RECORD EH;
EH.ExceptionCode = STATUS_UNWIND_CONSOLIDATE;
EH.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
EH.NumberParameters = 4;
EH.ExceptionInformation[0] = (ULONG)CallCatch;
EH.ExceptionInformation[1] = EstFrame;
EH.ExceptionInformation[2] = dispatcher->ImageBase + aHandler->Handler;
EH.ExceptionInformation[3] = aCatch->TryLow;
rtl.RtlUnwindEx(estFrame, dispatcher->ControlPc, #EH, NULL, Context, dispatcher->HistoryTable);
Call catch should take a function with EXCEPTION_RECORD* as parameter, call the actual catch and returning the continuation address for this catch.

Spring LDAP AD paging support not working - LDAP: error code 12 - 00000057: LdapErr: DSID-0C09079A

When trying to run the code above I'm getting javax.naming.OperationNotSupportedException with the message:
[LDAP: error code 12 - 00000057: LdapErr: DSID-0C09079A, comment: Error processing control, data 0, v2580].
The first page is successfully retrieved and the exception is thrown only at second loop iteration.
public void pagedResults() {
PagedResultsCookie cookie = null;
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
int page = 1;
do {
logger.info("Starting Page: " + page);
PagedResultsDirContextProcessor processor = new PagedResultsDirContextProcessor(20, cookie);
List<String> lastNames = ldapTemplate.search("", initialFilter.encode(), searchControls, UserMapper.USER_MAPPER_VNT, processor);
for (String l : lastNames) {
logger.info(l);
}
cookie = processor.getCookie();
page = page + 1;
} while (null != cookie.getCookie());
}
However, when I remove Spring LDAP using pure implementation as above, it works!
try {
LdapContext ctx = new InitialLdapContext(env, null);
// Activate paged results
int pageSize = 5;
byte[] cookie = null;
ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.CRITICAL) });
int total;
do {
/* perform the search */
NamingEnumeration results = ctx .search("",
"(&(objectCategory=person)(objectClass=user)(SAMAccountName=vnt*))",
searchCtls);
/* for each entry print out name + all attrs and values */
while (results != null && results.hasMore()) {
SearchResult entry = (SearchResult) results.next();
System.out.println(entry.getName());
}
// Examine the paged results control response
Control[] controls = ctx.getResponseControls();
if (controls != null) {
for (int i = 0; i < controls.length; i++) {
if (controls[i] instanceof PagedResultsResponseControl) {
PagedResultsResponseControl prrc = (PagedResultsResponseControl) controls[i];
total = prrc.getResultSize();
if (total != 0) {
System.out.println("***************** END-OF-PAGE "
+ "(total : " + total
+ ") *****************\n");
} else {
System.out.println("***************** END-OF-PAGE "
+ "(total: unknown) ***************\n");
}
cookie = prrc.getCookie();
}
}
} else {
System.out.println("No controls were sent from the server");
}
// Re-activate paged results
ctx.setRequestControls(new Control[] { new PagedResultsControl(
pageSize, cookie, Control.CRITICAL) });
} while (cookie != null);
ctx.close();
} catch (NamingException e) {
System.err.println("PagedSearch failed.");
e.printStackTrace();
} catch (IOException ie) {
System.err.println("PagedSearch failed.");
ie.printStackTrace();
}
Any hints?
The bad thing about LDAP paged results is that they only work if the same underlying connection is used for all requests. The internals of Spring LDAP get a new connection for each LdapTemplate operation, unless you use the transactional support.
The easiest way to make sure the same connection will be used for a sequence of LDapTemplate operations is to use the transaction support, i.e. configure transactions for Spring LDAP and wrap the target method with a Transactional annotation.
I managed to make my example above work using SingleContextSource.doWithSingleContext approach.
However my scenario is different, my app is service oriented and the paged results as well as the cookie should be sent to an external client so that he decides to request next pages or not.
So as far as I can tell, spring-ldap does not support such case. I must use pure implementation so that I can keep track of the underlying connection during requests. Transaction support could help as well as SingleContextSource, but not among different requests.
#marthursson
Is there any plan in spring ldap to such support in the future?
I found I could use your first example (Spring) as long as I set the ignorePartialResultException property to true in my ldapTemplate configuration and put the #Transactional on my method as suggested.
you can replace ldapTemplate DirContext like this
ldapTemplate.setContextSource(new SingleContextSource(ldapContextSource().getReadWriteContext()));

Handling AccessViolation exception in try catch c#

How to catch the AccessViolation exception in try-catch block:
here is the code below:
public static BP GetBloodPressure(string vendorid, string productid)
{
BP Result = new BP();
try
{
GETBPData BPreadings = new GETBPData();
UInt16 VendorId = Convert.ToUInt16(vendorid, 16);
UInt16 ProductId = Convert.ToUInt16(productid, 16);
if (HealthMonitorData.HidDataTap_GetBloodPressure(VendorId, ProductId, ref BPreadings)) // error here
{
if (BPreadings.ucSystolic == 0 && BPreadings.ucDiastolic == 0 && BPreadings.DeviceId1 == 0 && BPreadings.DeviceId2 == 0 && BPreadings.ucPulse == 0)
{
Result = null;
}
else
{
Result.UcSystolic = BPreadings.ucSystolic;
Result.UcDiastolic = BPreadings.ucDiastolic;
Result.UcPulse = BPreadings.ucPulse;
Result.DeviceId1 = BPreadings.DeviceId1;
Result.DeviceId2 = BPreadings.DeviceId2;
}
}
}
catch (Exception ex)
{
}
return Result;
}
I am importing one dll to read the blood pressure values from the device. I have try to catch the exception but the control does not go beyond the "if" statement where the access violation exception is coming.
Kindly Suggest?
Thanks
Handling of AccessViolationExceptions and other corrupted state exceptions has been changed in .NET 4. Generally you should not catch these exceptions, so the runtime has been changed to reflect this. If you really need to catch these, you must annotate the code with the HandledProcessCorruptedStateExceptions attribute.
Please keep in mind, that the behavior was changed with good reason. Most applications will not be able to handle these exceptions in any meaningful way and thus should not catch them.
its HandleProcessCorruptedStateExceptions not HandleDProcessCorruptedStateExceptions

Resources