I am working with the ClassLoader class and if there are problems it throws a NoClassDefFoundError. In context this is actually not a fatal error.
Is there a good way to catch the error and throw as exception?
try{
myClassLoader.makeClass(className, classData);
}
catch(Throwable t){
log.error("Class load failed");
// throw as an Exception instead
}
Does this make sense? I don't want this to be fatal but rather just exit without return. The key here is that I want the full stack trace and information associated with the NoClassDefFoundError. It is simple to catch the error it is harder to keep all of the associated information.
throw new Exception("message", t);
t is Throwable
You can catch the exception and throw a new one very easily.
try{
myClassLoader.makeClass(className, classData);
}catch(ClassNotFoundException err){
throw new Exception("Oh no! An error occurred!");
}
Adding onto #bwfcwalshy's answer, we should never catch errors in a Java program. Consider a scenario where program runs out of memory, in this case, an OutOfMemoryError will be thrown. If we have catch block to catch Error (or Throwable), it will catch that error but won't have memory to execute anything, resulting in that error getting suppressed.
We should always catch Exception, not Error or Throwable.
Generally speaking you wouldn't catch a java.lang.Error.
But assuming that this is really what you want to do, you can just catch the Error and throw an Exception.
try {
// Error occurred
} catch(Error e){
throw new Exception("Error", e);
}
Related
I have a ITestListener to note test results. In my locator class if I try to handle something in catch statement, none of the code inside the catch is executed. For ex : I am trying to handle a WebElement that may or may not throw exception. When it throws exceptions, I should handle in the catch statement and locate different element. Since catch statement is not being executed and when the exception occurs, the applications just halts. Is there a way I could run the catch statement even when onTestFailure method is ON from TestNG ? Please suggest a solution.
//Test Script
public boolean loginVerification(String username, String password) {
try {
utilities.click(helloSignInLink, "elementToBeClickable");
reportLog("debug","info","Clicked on SignIn link");
utilities.sendText(loginID, username);
reportLog("debug","info","Username entered");
utilities.sendText(passwordID, password);
reportLog("debug","info","Password entered");
utilities.click(submit, "elementToBeClickable");
reportLog("debug","info","Clicked on submit button");
Thread.sleep(2000);
isTrue = driver.getTitle().contains("Vectors");
}
catch(Exception e) {
reportLog("debug","info","Unable to login with username : "+username+" , error message : "+e);
isTrue = false;
}
return isTrue;
}
I would recommend to catch Throwable - not just an Exception. Another thing is that when you catch something the excepttion does not really go up the stack so TestNG would never know if anything went wrong in your test and test listener would not detect failure. There is the way to push the exception further on after you have cought it. Like:
catch(Throwable e) {
reportLog("debug","info","Unable to login with username : "+username+" , error message : "+e);
isTrue = false;
throw e;
}
Can you correct your approach and let us know if the issue still exists?
P.S. - I also cannot see any assertions in your code. Assert results or Exception define the test result.
That means you are not catching the same error catch block.
Either use the same exception like TimeoutException so this block will only if TimeoutException occur. If you not sure about the error use generic exception block like Exception it will for sure going to execute if any error occur. In this case Exception will not execute for TimeoutException only because you have already specify same
try {
System.out.println("Your code");
}catch(TimeoutException t) {
System.out.println(t.getMessage());
}catch(Exception ex) {
ex.getStackTrace();
}
I am trying to handle the exceptions that are a part of the java.net package. I went through the documentation and I saw 12 exceptions belonging to that package, but I couldn't find the parent class of these exceptions.
So far what I have tried is:
catch(Exception e)
{
if(e instanceof org.openqa.selenium.WebDriverException)
sendException("Problem is with the selenium web driver");
else if(e instanceof java.net.Exception) //I need help with this line
sendException("There is some problem with the network");
}
After trying this, I get the following error message
unable to resolve class java.net.Exception
How can I catch the java.net exceptions?
java.net.Exception doesn't exist and you cannot catch exceptions of classes from a specific package in this way.
Considering that network exceptions always start by java.net is wrong too.
Some network exception don't start by java.net and exceptions can also be wrapped by another exception. For example java.net.SocketException could be wrapped by java.lang.IllegalStateException.
You will not handle it because that is not a java.net exception.
Handling the exception with instanceOf looks not helpful either.
Specifying a specific exception in the catch clause is enough.
Note also that an exception is self-explanatory and should contain in its state all relevant information : you don't need to map the exception to a textual message as you do.
What you want to send/log is exploiting the exception class/message/cause/stracktrace associated to. What you do is just interpretation of the exception meaning that would be error prone.
so do that :
catch(Exception e){
sendException(e);
}
public void sendException(Exception e){
// exploit e.getClass(), e.getMessage() or e.getStackTrace()
...
}
Note that in some cases you want to catch some specific exceptions because you have a specific processing for them :
catch(WebDriverException e){
processWebDriverException(e);
}
catch(Exception e){
processAnyOtherException(e);
}
First off, the reason that you can't catch java.net.Exception. The Exception class is in the java.lang and it is NOT the exception you should be catching.
So what should you catch?
Unfortunately, there there is no suitable supertype for all networking exceptions and no non-networking others. But it turns out that most networking exceptions have java.io.IOException as an ancestor.
(There is one java.net.* exception that doesn't descend from IOException; i.e. java.net.URISyntaxException. But that is an unchecked exception, and it is not indicative of a "network problem".)
So one approach would be to catch IOException. You could further refine this by using reflection to get the package name of the exception class (see https://stackoverflow.com/a/57002571/139985); e.g.
} catch (org.openqa.selenium.WebDriverException e) {
sendException("Problem is with the selenium web driver");
} catch (IOException e) {
if (e.getClass().getPackage().startsWith("java.net"))
sendException("There is some problem with the network");
else {
throw e; // Or diagnose differently
}
}
java.net.Exception doesn't exist, java.lang.Exception does.
To check that the package is java.net, use e.getClass().getPackage():
catch(Exception e)
{
if(e instanceof org.openqa.selenium.WebDriverException)
sendException("Problem is with the selenium web driver");
else if(e.getClass().getPackage().startsWith("java.net"))
sendException("There is some problem with the network");
}
You can catch java.net Exceptions like this :
try {
}
catch (
BindException
| ConnectException
| HttpRetryException
| MalformedURLException
| NoRouteToHostException
| PortUnreachableException
| ProtocolException
| SocketException
| SocketTimeoutException
| UnknownHostException
| UnknownServiceException
| URISyntaxException
e
){
// do stuff with e
}
But what is the point if you are going to call instanceof after to process each exception differently?
In this case you should use different catch blocks.
If there is no common superclass, there is no way to catch these exceptions in a single clause. You might want to check out this post, but I would agree with you that it's not pretty if you have to specify 12 exceptions:
Can I catch multiple Java exceptions in the same catch clause?
Example
Try{
Code where your exception occuring
}
Catch(Exception e){
e.printStackTrace();
}
I have a Guava retryer around some code:
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfExceptionOfType(Exception.class)
.withStopStrategy(MoreStopStrategies.liveStopAfterAttempt(retries))
.withWaitStrategy(MoreWaitStrategies.liveExponentialWait(TimeUnit.MILLISECONDS, retrySleep, TimeUnit.MILLISECONDS))
.build();
try {
retryer.call(() -> {
return doStuff();
});
} catch (ExecutionException | RetryException e) {
throw Throwables.propagate(e);
}
Let's say doStuff() throws an ArithmeticException. How do I catch that outside the retryer.call()?
So the retryer will try a couple times, fail, and enter into the catch (ExecutionException | RetryException e) block. How would I retrieve the ArithmeticException inside there?
Thanks!
This is a bit of a faulty pattern. You say that any exception is ok to retry. An ArithmeticException will then be ok to retry. This is not what you want.
This is how retries should be implemented. Note the comment on the second line.
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
// .retryIfExceptionOfType(Exception.class)
.withStopStrategy(MoreStopStrategies.liveStopAfterAttempt(retries))
.withWaitStrategy(MoreWaitStrategies.liveExponentialWait(TimeUnit.MILLISECONDS, retrySleep, TimeUnit.MILLISECONDS))
.build();
void doStuff() {
try {
retryer.call(() -> {
doRealStuff();
});
} catch (RetryException e) {
throw new RuntimeException("Call never succeeded", e);
} catch (ExecutionException e) {
Throwables.propagateIfPossible(e.getCause(), ArithmeticException.class);
throw new RuntimeException("Unexpected", e);
}
}
Then when you actually call doStuff:
try {
doStuff();
} catch(ArithmeticException e) {
System.err.println("Arithmetic exception caught:");
e.printStackTrace(System.err);
}
Without seeing your doStuff() or at least knowing what kinds of Exceptions it throws it's hard to answer.
In general, if you have the Retryer consider every Exception unsuccessful, it will retry and eventuelly stop - but it catches any Throwable thrown inside the executed code (see Retryer code, line 162)
The solution is either:
If your doStuff() only throws an ArithmeticException in those cases that result in stopping the Retryer, and that a different kind of Exception marks that a retry is necessary, you can do retryIfExceptoinOfType(OtherException.class). Then, according to the docs the docs
Throws:
java.util.concurrent.ExecutionException - if the given callable throws an exception, and the rejection predicate considers the attempt as successful. The original exception is wrapped into an ExecutionException.
call() will throw an ExecutionException that you can catch outside of the Retryer and inspect the wrapped Exception.
If ArithmeticExcpetion is all doStuff() will throw, and that also indicates that the Retryer should retry, then you can write a custom StopStrategy that throw an ArithmeticExpcetion, it is catched nowhere in the Retryer.
However I advise you to completele rewrite your code, your data flow seems a bit broken. If an ArithmeticExpcetion (or actually even any Exception, as you specify Exception.class in the retryIf ) is to be expected, it should not also be unexpected and need special handling.
I have a small method that looks like this:
public static void unstarTrack(Context ctxContext, String strId) {
try {
HttpParams htpParameters = new BasicHttpParams();
List<NameValuePair> lstCredentials = new ArrayList<NameValuePair>();
lstCredentials.add(new BasicNameValuePair("t", String.valueOf(System.currentTimeMillis() / 1000)));
lstCredentials.add(new BasicNameValuePair("__call", "favourites.removeSong"));
HttpPost htpPost = new HttpPost(API_URL);
htpPost.setEntity(new UrlEncodedFormEntity(lstCredentials));
htpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:18.0) Gecko/20100101 Firefox/18.0");
htpPost.addHeader("Accept-Encoding", "gzip");
DefaultHttpClient dhcClient = new DefaultHttpClient(htpParameters);
HttpResponse resResponse = dhcClient.execute(htpPost);
Log.d(TAG, EntityUtils.toString(resResponse.getEntity()));
return;
} catch (SocketException e) {
throw new RuntimeException("problem with network connectivity.", e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Encoding not supported.", e);
} catch (ClientProtocolException e) {
throw new RuntimeException("A protocol exception was encountered.", e);
} catch (ParseException e) {
throw new RuntimeException("An error occurred while trying to read the header elements.", e);
} catch (IOException e) {
throw new RuntimeException("An error occurred while trying to read response stream.", e);
}
}
The method itself is quite simple but it has a bunch of exceptions that an occur and I don't know how I should handle those. Suppressing them by doing a simple ´e.printStackTrace()´ doesn't seem like a nice idea so I began reading up on exception-handling best-practices but I still am a bit lost. What should I do with the exceptions?
I need to do something with my exceptions because I don't want to return null from the method. Returning a null from my method means that the the calling method will have no insight as to whether an exception happened inside my method.
Should I create a custom exception and raise that or should I simply raise unchecked exceptions?
The calling method can't really do much to affect my method i.e. a SocketException may occur if there was a problem with the network connectivity, and a IOException may occur if there was a problem reading the stream. The most that the calling method can do is to retry this at a later time.
If I re-throw all the exceptions that I have trapped, the calling method would simply get riddled with exception-handling blocks.
(I'm sorry if this seems like a trivial question. I'm simply trying to learn to write better code. Thanks.)
Create a dedicated exception, which has the appropriate abstraction level (something like UnstarTrackException). Throw such an exception, wrapping the original exception you caught. That way, the caller will only have to handle one exception (I assume all the exceptions should be handled the same way: retrying).
Whether this exception should be checked or not depends on your taste. If you want to force all the callers of your method to handle this exception, make it a checked exception. If you want to let the caller choose whether he wants to handle this exception or not, use a runtime exception.
If this method is buried deep inside layers of code, and if an exception can only be handled at the top layer, a runtime exception is probably a better choice. And in fact, unless you're the only caller of this method, a runtime exception is also probably a better choice. Checked exceptions tend not to be used much nowadays.
My code looks like this :
try
{
String htmlPageText=readFromHtml("http://www.yahoo.com");
}
catch (Exception e)
{
System.out.println("===Here===");
}
Method readFromHtml() will take a URL and return an HTML page. Normally it works fine. But I'm trying to simulate a "site down" situation, so I unplugged the Internet connection. I thought, the error should be caught and the result will be "===Here===", but instead, it returned:
java.net.UnknownHostException: http://www.yahoo.com"
and never printed out "===Here===". UnknownHostException is an extension of java.lang.Exception, so why was it not caught in the catch clause? Do I need a catch (UnknownHostException ex) to get it?
What is the readFromHTML method source code ? My guess is that this method throws some kind of exception but not UnknownHostException... Somewhere else in your code the exception is left unhandled.