So I recently asked the question of how to handle Dropbox API Exceptions here. I learned that I would have to parse the DBXEception into its subclasses which there are many of. Now Thinking about this I am wondering what would be the best way to go about handling this.
Currently I plan on using instanceof and checking like this if I want the program to try again it will return true and the program will try again maybe with a exponential backoff with server request
public boolean parseDBX(DbxException e)
{
if(e instanceof AccessErrorException) {//handle Error
}else if (e instanceof DbxApiException) {//handle Error
}etc
}
It would be called in a catch block like this
for(int i =0;;i++) {
try {
ListFolderResult result = client.files().listFolder("/Saves/"+prefName);
while (true) {
for (Metadata metadata : result.getEntries()) {
System.out.println(metadata.getPathLower());
//metadata.
}
if (!result.getHasMore()) {
break;
}
result = client.files().listFolderContinue(result.getCursor());
}
} catch (ListFolderErrorException e) {
createDefFolder();
} catch (DbxException e) {
if(codeHandler.parse(e)&&i<10) {
continue;
}else {
log.write("Error 5332490: a problem was encountered while trying to check for the root file"+e.getMessage());
throw new IOException();
}
}
}
So My Question is there a way to use a switch statement instead(From what I have found the answer is no), and if not, is there a better way to handle checking for the type of exception.
The best approach is to avoid "parsing" the exception at all by catching exceptions of the appropriate type:
try {
...
} catch (AccessErrorException aee) {
...
} catch (DbxApiException dae) {
...
}
In cases when this is not desirable you could associate your own integer ID with each exception type, put it in a Map, and use it in your parse method to distinguish among subtypes in a switch:
static Map<Class,Integer> parseId = new HashMap<>();
static {
parseId.put(AccessErrorException.class, 1);
parseId.put(DbxApiException.class, 2);
...
}
...
public void parseDBX(DbxException e) {
Integer id = parseId.get(e.getClass());
if (id != null) {
switch (id.intValue()) {
...
}
}
}
Related
Here is my code:
whatever exception it throws I don't want to catch it outside, I want to continue my loop again by handling it separately. I don't want to use another try catch inside this try catch. Can someone guide me on this?
I don't want to use another try catch inside this try catch.
Yes you do.
MarketplaceBO marketplaceBOObject = new MarketplaceBO(entity.getMarketplaceID());
try {
marketplaceBOObject.loadFromSable();
} catch (WhateverException e) {
// Do something here, or, if you prefer, add the exception to a list and process later
doSomething() ;
// Continue your loop above
continue ;
}
if (marketplaceBOObject.isActive()) {
If you REALLY don't want to do this, your loadFromSable() method could return some object that provides information about success/failure of the call. But I wouldn't recommend that.
do this way -- this way your rest of the code will run no matter there is an exception or not
for (MerchantMarketplaceBO entity : merchantMarketplaceBOList) {
MarketplaceBO marketplaceBOObject = new MarketplaceBO(entity.getMarketplaceID());
try{
marketplaceBOObject.loadFromSable();
if (marketplaceBOObject.isActive()) {
resultVector.add(marketplaceBOObject.getCodigoMarketplace());
}
}
catch{
if (marketplaceBOObject.isActive()) {
resultVector.add(marketplaceBOObject.getCodigoMarketplace());
}
}
}
Another "trick" to deal with that is to move the body to the loop into a separate method having the "additional" try/catch block:
private MarketplaceBO loadFromSable(MerchantMarketplaceBO entity){
MarketplaceBO marketplaceBOObject = new MarketplaceBO(entity.getMarketplaceID());
try {
marketplaceBOObject.loadFromSable();
} catch (WhateverException e) {
// do something to make marketplaceBOObject a valid object
// or at least log the exception
}
return marketplaceBOObject;
}
But since we want to stick to the Same Layer of Abstraction principle we also need to move other part of that method to new smaller methods:
public void serveFromSableV2() {
String merchantCustomerID = ObfuscatedId.construct(request.getMerchantCustomerID()).getPublicEntityId();
try {
List<MerchantMarketplaceBO> merchantMarketplaceBOList =
getAllMerchantMarketplacesBOsByMerchant();
Vector<Marketplace> resultVector = new Vector<>();
for (MerchantMarketplaceBO entity : merchantMarketplaceBOList) {
MarketplaceBO marketplaceBOObject = loadFromSable(entity);
addToActiveMarketplacesList(marketplaceBOObject,resultVector);
}
verifyHavingActiveMarketPlaces(resultVector);
setResponseWithWrapped(resultVector);
} catch (EntityNotFoundException | SignatureMismatchException | InvalidIDException e) {
throw new InvalidIDException("merch=" + merchantCustomerID + "[" + request.getMerchantCustomerID() + "]"); //C++ stack throws InvalidIDException if marketplace is not found in datastore
}
}
You could refactor the load into a separate method that catches and returns the exception instead of throwing it:
private Optional<Exception> tryLoadFromSable(MarketplaceBO marketplaceBOObject) {
try {
marketplaceBOObject.loadFromSable();
return Optional.empty();
}
catch(Exception e) {
return Optional.of(e);
}
}
Then inside your loop:
//inside for loop...
MarketplaceBO marketplaceBOObject = new MarketplaceBO(entity.getMarketplaceID());
Optional<Exception> loadException = tryLoadFromSable(marketplaceBOObject);
if(loadException.isPresent()) {
//Do something here, log it, save it in a list for later processing, etc.
}
I'm finding myself writing alot of retry loops that look like
int triesRemaining = 3;
while (triesRemaining > 0) {
try {
<MY FUNCTION CALL>
LOGGER.info("success");
break;
} catch (Exception e) {
if (e.getCause() instanceof SocketTimeoutException) {
triesRemaining--;
LOGGER.info(e.getMessage() + " trying again. Tries Remaining: " + triesRemaining);
} else {
LOGGER.error(e.getMessage(), e);
return;
}
}
}
if (triesRemaining == 0) {
LOGGER.error("Failed over too many times");
}
I want to write a generic function that accepts a Lambda and only retries on a specific error (in the above case thats SocketTimeoutException). I've seen some functions that accept a Runnable which is fine, but they don't seem to allow limiting to specific exceptions.
Any advice?
Well it's already done. It also accepts list of exceptions on which you want to retry. It also provides linear/exponential retry strategies.
Have a look https://github.com/rholder/guava-retrying
A simple example from it's readme, you can compose and use a retryer like:-
Callable<Boolean> callable = new Callable<Boolean>() {
public Boolean call() throws Exception {
return true; // do something useful here
}};
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfResult(Predicates.<Boolean>isNull())
.retryIfExceptionOfType(IOException.class)
.retryIfRuntimeException()
.withStopStrategy(StopStrategies.stopAfterAttempt(3))
.build();
try {
retryer.call(callable);
} catch (RetryException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
Have a look to org.springframework.retry
There is an annotation #Retryable which corresponding to your need. You can specify the type of exception to retry and configure the number of attempt, etc...
Check out Failsafe:
RetryPolicy retryPolicy = new RetryPolicy()
.retryOn(SocketTimeoutException.class)
.withMaxRetries(3);
Failsafe.with(retryPolicy)
.onRetry((c, f, ctx) -> log.warn("Failure #{}. Retrying.", ctx.getExecutions()))
.onFailure(e -> LOGGER.error(e.getMessage(), e))
.run(() -> myFunctionCall());
What's the problem of just making this function to accept a Runnable argument and then run it in <MY FUNCTION CALL>?
public static void retry(Runnable r) {
// ...
while (triesRemaining > 0) {
try {
r.run();
LOGGER.info("success");
break;
}
// ...
}
then call it (if you prefer - with a lambda):
retry(() -> {
connectToServer();
// todo what-ever-you-want
});
I believe you're looking for pure Java based solution. Based on assumption, I would say Java 8 uses functional interface, an interface with single abstract method. I would create a new RetryCommand class that has a run method which takes in a function.
I would like to annotate some of my test cases with KnownFault - which would do pretty much what expectedException does plus some magic using YouTrack's REST API. I would also like to have an IntermittentFailure attribute which would mean that I'm aware that the test might occasionally fail with [exception] [message] but I wouldn't want this to block the rest of my build chain.
After some research I found that my test class should implement IHookable, then I could have something like this:
#Override
public void run(IHookCallBack callBack, ITestResult result) {
callBack.runTestMethod(result);
if (result.getThrowable().getCause() instanceof IllegalArgumentException){
System.out.println("This is expected.");
result.setThrowable(null);
}
else{
System.out.println("Unexpected exception");
}
}
The problem with this is the actual implementation of invokeHookable:
final Throwable[] error = new Throwable[1];
IHookCallBack callback = new IHookCallBack() {
#Override
public void runTestMethod(ITestResult tr) {
try {
invokeMethod(thisMethod, testInstance, parameters);
} catch (Throwable t) {
error[0] = t;
tr.setThrowable(t); // make Throwable available to IHookable
}
}
#Override
public Object[] getParameters() {
return parameters;
}
};
hookable.run(callback, testResult);
if (error[0] != null) {
throw error[0];
}
Unfortunately that last line means that my test case is going to throw an exception no matter what as the error array is completely out of my hands in the run method.
So, what would be the proper way of intercepting an exception and handling it the way I want to?
What you are trying to do is really interesting. You should try to propose changes on https://github.com/cbeust/testng/pull/
But maybe IHookable is not the best listener you can use. Did you try IInvokedMethodListener?
void afterInvocation(IInvokedMethod method, ITestResult result) {
if (result.getThrowable().getCause() instanceof IllegalArgumentException) {
System.out.println("This is expected.");
result.setThrowable(null);
result.setStatus(SUCCESS); // If you want to change the status
} else {
System.out.println("Unexpected exception");
}
}
I'm trying to write a job scheduling system in GWT that maintains an array of exceptions (Class<? extends Exception>[] exceptions), that might be resolved by retrying the job. For this, if the scheduler catches an exception, I need to see if this exception matches one of the classes in the array. So, I would like to have a function like this:
boolean offerRetry(Exception exception) {
for (Class<? extends Exception> e: exceptions)
if (e.isInstance(exception)) return true;
return false;
}
Unfortunately Class.isInstance(...) isn't available in GWT.
Is there a good work-around for this? My current best guess is something like this:
public static boolean isInstance(Class<?> clazz, Object o) {
if ((clazz==null) || (o==null)) return false;
if (clazz.isInterface()) throw new UnsupportedOperationException();
Class<?> oClazz = o.getClass();
while (oClazz!=null) {
if (oClazz.equals(clazz)) return true;
oClazz = oClazz.getSuperclass();
}
return false;
}
Unfortunately, this approach does not support testing against interfaces, and I don't have any idea how to fix that either as Class.getInterfaces() is also not available. But would this approach at least work the same way as Java's Class.isInstance in all other cases, excluding interfaces? Specifically, if I look at GWT's source for Class.java, the getSuperclass() method contains a check of isClassMetadataEnabled(), which might return false (but I don't know in which cases), as it contains a comment saying "This body may be replaced by the compiler".
Or is there a better way entirely to do this?
I use following code:
public static <T> boolean isInstanceOf(Class<T> type, Object object) {
try {
T objectAsType = (T) object;
} catch (ClassCastException exception) {
return false;
}
return true;
}
Maybe something like this would help:
boolean offerRetry(Exception exception) {
try{
throw exception;
} catch (SpecException se) {
return true;
} catch (SpecException1 se1) {
return true;
...
} catch (Exception e) {
return false;
}
}
It depends on how you construct the array of exceptions. If the java 7 stuff works properly then you could put all exceptions in one catch:
boolean offerRetry(Exception exception) {
try{
throw exception;
} catch (SpecException | SpecException1 | ... se) {
return true;
} catch (Exception e) {
return false;
}
}
There are some task that should't be done in parallel, (for example opening a file, reading, writing, and closing, there is an order on that...)
But... Some task are more like a shoping list, I mean they could have a desirable order but it's not a must..example in communication or loading independient drivers etc..
For that kind of tasks,
I would like to know a java best practice or pattern for manage exceptions..
The java simple way is:
getUFO {
try {
loadSoundDriver();
loadUsbDriver();
loadAlienDetectorDriver();
loadKeyboardDriver();
} catch (loadSoundDriverFailed) {
doSomethingA;
} catch (loadUsbDriverFailed) {
doSomethingB;
} catch (loadAlienDetectorDriverFailed) {
doSomethingC;
} catch (loadKeyboardDriverFailed) {
doSomethingD;
}
}
But what about having an exception in one of the actions but wanting to
try with the next ones??
I've thought this approach, but don't seem to be a good use for exceptions
I don't know if it works, doesn't matter, it's really awful!!
getUFO {
Exception ex=null;
try {
try{ loadSoundDriver();
}catch (Exception e) { ex=e; }
try{ loadUsbDriver();
}catch (Exception e) { ex=e; }
try{ loadAlienDetectorDriver();
}catch (Exception e) { ex=e; }
try{ loadKeyboardDriver()
}catch (Exception e) { ex=e; }
if(ex!=null)
{ throw ex;
}
} catch (loadSoundDriverFailed) {
doSomethingA;
} catch (loadUsbDriverFailed) {
doSomethingB;
} catch (loadAlienDetectorDriverFailed) {
doSomethingC;
} catch (loadKeyboardDriverFailed) {
doSomethingD;
}
}
seems not complicated to find a better practice for doing that.. I still didn't
thanks for any advice
Consider the execute around idiom.
Another option (which isn't really all that different, it just decouples them more) is to do each task in a separate thread.
Edit:
Here is the kind of thing I have in mind:
public interface LoadableDriver {
public String getName();
public void loadDriver() throws DriverException;
public void onError(Throwable e);
}
public class DriverLoader {
private Map<String, Exception> errors = new HashMap<String, Exception>();
public void load(LoadableDriver driver) {
try {
driver.loadDriver();
} catch (DriverException e) {
errors.put(driver.getName(), e);
driver.onError(e);
}
}
public Map<String, Exception> getErrors() { return errors; }
}
public class Main {
public void loadDrivers() {
DriverLoader loader = new DriverLoader();
loader.loadDriver(new LoadableDriver(){
public String getName() { return "SoundDriver"; }
public void loadDriver() { loadSoundDriver(); }
public void onError(Throwable e) { doSomethingA(); }
});
//etc. Or in the alternative make a real class that implements the interface for each driver.
Map<String, Exception> errors = loader.getErrors();
//react to any specific drivers that were not loaded and try again.
}
}
Edit: This is what a clean Java version would ultimately look like if you implemented the drivers as classes (which is what the Java OO paradigm would expect here IMHO). The Main.loadDrivers() method would change like this:
public void loadDrivers(LoadableDriver... drivers) {
DriverLoader loader = ...
for(LoadableDriver driver : drivers) {
loader.load(driver);
}
//retry code if you want.
Set<LoadableDriver> failures = loader.getErrors();
if(failures.size() > 0 && tries++ > MAX_TRIES) {
//log retrying and then:
loadDrivers(drivers.toArray(new LoadableDriver[0]));
}
}
Of course I no longer use a map because the objects would be self-sufficient (you could get rid of the getName() method as well, but probably should override toString()), so the errors are just returned in a set to retry. You could make the retry code even simpler if each driver was responsible for knowing how often it should it retry.
Java won't look as nice as a well done C++ template, but that is the Java language design choice - prefer simplicity over complex language features that can make code hard to maintain over time if not done properly.
Try this:
protected void loadDrivers() {
loadSoundDriver();
loadUsbDriver();
loadAlienDetectorDriver();
loadKeyboardDriver();
}
Then:
protected void loadSoundDriver() {
try {
// original code ...
}
catch( Exception e ) {
soundDriverFailed( e );
}
}
protected void soundDriverFailed( Exception e ) {
log( e );
}
This gives subclasses a chance to change the behaviour. For example, a subclass could implement loading each driver in a separate thread. The main class need not care about how the drivers are loaded, nor should any users of the main class.
IMO, for your case, if the exception is "ignorable" it's best if the "loadSoundDriver" method catches the exception and simply returns an error.
Then in the function that loads stuff, you can record all the errors and at the end of the sequence, decide what to do with them.
[edit]
Something like this:
// init
MyError soundErr = loadSoundDriver();
MyError otherErr = loadOtherDriver();
if(soundErr!=null || otherErr !=null){
// handle the error(s)
}
Just surround every single load operation with its own try / catch block.
try {
loadSoundDriver();
} catch (loadSoundDriverFailed) {
doSomethingA;
}
try {
loadUsbDriver();
} catch (loadUsbDriverFailed) {
doSomethingB;
}
// ...
So you can handle every exception by itself and continue processing the oder operations.