Java throw e becomes null on Android - java

I have the following:
try {
response.statusCode = urlConnection.getResponseCode();
} catch(IOException e) {
throw e;
}
I look at the debugger and e = UnknownHostException
After the throw I have:
try {
NetworkResponse response = NetworkHelper.getByURL(url);
} catch(Exception e) { <------- IT LANDS HERE, BUT e=null
ExceptionHelper.announce(e);
throw e;
}
So after the throw my catch block gets the exception but it's null.
The debugger shows e=null.
I have no idea why this would happen.

I don't even see the point of catching the exception if you just immediately rethrow it. Add a throws IOException to that method and let the other catch handle it.

Related

Throw new Exception and have a block where one catches any exception

private WebElement findElementByXpath(WebDriver driver, String xpath) throws WebElementNotFoundException, HopelessAccountException {
WebElement element = null;
try {
element = new WebDriverWait(driver, Duration.ofSeconds(dirationInSeconds))
.until(ExpectedConditions.elementToBeClickable(By.xpath(xpath)));
} catch (TimeoutException timeoutException) {
loggingService.timeMark("findElementByXpath", "TimeoutException");
throw new WebElementNotFoundException();
} catch (UnhandledAlertException alertException) {
loggingService.timeMark("findElementByXpath", "alertException");
final String LIMITS_EXHAUSTED_MESSAGE = "Not enough limits!";
String message = alertException.getMessage();
if (message.contains(LIMITS_EXHAUSTED_MESSAGE)){
throw new HopelessAccountException(); // Attention.
}
} catch (Exception e) {
// Mustn't be here.
loggingService.timeMark("findElementByXpath", e.getMessage());
driver.quit();
System.out.println("QUIT!");
System.exit(0);
}
loggingService.timeMark("findElementByXpath", "end. Xpath: " + xpath);
return element;
}
Please, have a look at the line that I commented as "Attention".
I have caught the exception where there is not enough limits any more. And I throw the exception that the account is hopeless.
But it is immediately caught by just after the next few lines. Namely where I commented "Mustn't be here".
I would like to preserve this catching any exception. At least for debugging purpose.
Could you help me understand whether I can both throw HopelessAccountException and preserve the "catch Exception" block?
You can always modify your Exception block to rethrow e if it is an instance of HopelessAccountException:
} catch (Exception e) {
if (e instanceof HopelessAccountException) throw e; // preserves original stack trace
// Mustn't be here.
loggingService.timeMark("findElementByXpath", e.getMessage());
driver.quit();
System.out.println("QUIT!");
System.exit(0);
}
However as #fishinear indicates, in your posted code the Exception block would not be reached as a result of the throw of throw new HopelessAccountException() - if your actual code looked more like:
try {
try {
System.out.println("In A()");
// do something to cause an exception E3 (e.g. UnhandledAlertException)
throw new E3();
} catch (E3 e3) { // UnhandledAlertException
System.out.println("In E3 catch");
throw new E1(); // HopelessAccountException
}
} catch (Exception e) {
System.out.println("In Exception catch");
if (e instanceof E1) throw e; // rethrow HopelessAccountException
System.out.println("e: "+e);
}
Then the test-and-rethrow is possible.
Then when you rip out your debugging "try block" your code would behave the same (for the HopelessAcountException).
in your code that calls findElementByXpath(…) you could catch the broad Exception type there. This means in your findElementByXpath(…) method you could just handle the known exceptions and anything else could be captured in calling code

Caught and declared exception in Java?

In Java, if I declare and caught an exception, can I handle the exception in a caller anyway? Or it needs not to be caught to handle it by caller?
class A {
void first() throws Exception {
try {
throw new Exception("my exception")
} catch (Exception e) {
log.message("Error in first()", e.getCouse)
throw e
}
}
}
class B {
Result second(A a) {
try {
a.first()
} catch (Exception e) {
log.message("Caught in B class", e.message)
return new Result(result: null, error: e.message)
}
}
second(A a)
}
You can simply rethrow the exception you've caught (obviously the surrounding method has to permit this via its signature etc.). The exception will maintain the original stack trace.
catch (WhateverException e) {
throw e;
}
You can also wrap the exception in another one AND keep the original stack trace by passing in the Exception as a Throwable as the cause parameter:
try
{
...
}
catch (Exception e)
{
throw new YourOwnException(e);
}

Handling contained exceptions

I'm wondering how should one handle "contained" exceptions. Because the term isn't concrete enough, let me take an example of PrivilegedActionException.
In short, this exception will in its cause contain any checked exception thrown during the computation within PrivilegedAction.
Now if I have and method computate() throws IOException I'll - if executed on its own - handle it as:
try {
computate();
} catch (FileNotFoundException ex) {
// Handle file not found
} catch (SomeOtherSubtypeOfIOException ex) {
// handle that again
}
Now as this has been executed in PriviledgedAction the only exception I get is PrivilegedActionException:
try {
Subject.doAs(() -> computate());
} catch (PrivilegedActionException ex) {
// Now what?
}
I can get the IOException from previous example by calling ex.getCause() but how would that look like? The obvious way looks odd ...
catch (PrivilegedActionException ex) {
if (ex.getCause() instanceof FileNotFoundException.class) {
// handle FileNotFound
} else if (ex.getCause() instanceof xxx) {
// something else
}
}
You could get the cause and re-throw it. Then handle exception with an outer try-catch.
catch (PrivilegedActionException ex) {
Throwable cause = ex.getCause();
if(cause !=null) throw ex.getCause();
else ex.printStackTrace();
}

rethrow java exception with new message, preserving the exception type if it is in the method declaration list

I am trying to create a helper method that will eliminate the need of having code like this:
void foo() throws ExceptionA, ExceptionB, DefaultException {
try {
doSomething(); // that throws ExceptionA, ExceptionB or others
} catch (Exception e) {
if (e instanceof ExceptionA)
throw new ExceptionA("extra message", e);
if (e instanceof ExceptionB)
throw new ExceptionB("extra message", e);
throw new DefaultException("extra message", e);
}
}
The problem is that I need to maintain the throws list in the function declaration and in the body of the function at the same time. I am looking how to avoid that and to make changing the throws list sufficient and my code to looks like:
void foo() throws ExceptionA, ExceptionB, DefaultException {
try {
doSomething(); // that throws ExceptionA, ExceptionB or others
} catch (Exception e) {
rethrow(DefaultException.class, "extra message", e);
}
}
Where rethrow method will be smart enough to recognize the throws list from the method declaration.
This way when I change the list of type that my method propagates in the throws list I to not need to change the body.
The following is a function that could solve the problem. The problem is because it does not know what type of exception it will throw its throws declaration has to say Exception, but if it does this, the method that is going to use it will need to specify it as well, and the whole idea of using the throws list goes to hell.
Any suggestions how this could be solved?
#SuppressWarnings("unchecked")
public static void rethrow(Class<?> defaultException, String message, Exception e) throws Exception
{
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
final StackTraceElement element = ste[ste.length - 1 - 1];
Method method = null;
try {
method = getMethod(element);
} catch (ClassNotFoundException ignore) {
// ignore the Class not found exception - just make sure the method is null
method = null;
}
boolean preserveType = true;
if (method != null) {
// if we obtained the method successfully - preserve the type
// only if it is in the list of the thrown exceptions
preserveType = false;
final Class<?> exceptions[] = method.getExceptionTypes();
for (Class<?> cls : exceptions) {
if (cls.isInstance(e)) {
preserveType = true;
break;
}
}
}
if (preserveType)
{
// it is throws exception - preserve the type
Constructor<Exception> constructor;
Exception newEx = null;
try {
constructor = ((Constructor<Exception>) e.getClass().getConstructor());
newEx = constructor.newInstance(message, e);
} catch (Exception ignore) {
// ignore this exception we prefer to throw the original
newEx = null;
}
if (newEx != null)
throw newEx;
}
// if we get here this means we do not want, or we cannot preserve the type
// just rethrow it with the default type
Constructor<Exception> constructor;
Exception newEx = null;
if (defaultException != null) {
try {
constructor = (Constructor<Exception>) defaultException.getConstructor();
newEx = constructor.newInstance(message, e);
} catch (Exception ignore) {
// ignore this exception we prefer to throw the original
newEx = null;
}
if (newEx != null)
throw newEx;
}
// if we get here we were unable to construct the default exception
// there lets log the message that we are going to lose and rethrow
// the original exception
log.warn("this message was not propagated as part of the exception: \"" + message + "\"");
throw e;
}
Update 1:
I can use RuntimeException to avoid the need of throws declaration, but in this case I am losing the type of the exception which is one of the most important points.
Ideas how I can resolve this?
I'm guessing that code where you're doing real work (ie. the part where you're not tinkering with exceptions) looks like this.
public void doSomeWork( ... ) throws ExceptionA, ExceptionB, DefaultException
{
try
{
// some code that could throw ExceptionA
...
// some code that could throw OtherExceptionA
...
// some code that could throw ExceptionB
...
// some code that could throw OtherExceptionB
}
catch (Exception e)
{
if( e instanceof ExceptionA )
{
throw new ExceptionA("extra message", e);
}
if( e instanceof ExceptionB )
{
throw new ExceptionB("extra message", e);
}
throw new DefaultException("extra message", e);
}
}
There are two better approaches
First Approach
public void doSomeWork( ... ) throws ExceptionA, ExceptionB, DefaultException
{
// some code that could throw ExceptionA
...
try
{
// some code that could throw OtherExceptionA
...
}
catch (Exception e)
{
throw new DefaultException("extra message", e);
}
// some code that could throw ExceptionB
...
try
{
// some code that could throw OtherExceptionB
}
catch (Exception e)
{
throw new DefaultException("extra message", e);
}
}
Second Approach
public void doSomeWork( ... ) throws ExceptionA, ExceptionB, DefaultException
{
try
{
// some code that could throw ExceptionA
...
// some code that could throw OtherExceptionA
...
// some code that could throw ExceptionB
...
// some code that could throw OtherExceptionB
}
catch (OtherExceptionA | OtherExceptionB e)
{
throw new DefaultException("extra message", e);
}
}
The first approach is good if you want to continue execution at all costs and catch and wrap RuntimeExceptions if you run into them. Generally you don't want to do this, and it's better to let them propagate up, as you probably can't handle them.
The second approach is generally the best. Here you're explicitly pointing out which exceptions you can handle, and dealing with them by wrapping them. Unexpected RuntimeExceptions propagate up, as they should unless you have some way of dealing with them.
Just a general comment: playing with StackTraceElements isn't considered to be a great idea. You may end up getting an empty array from Thread.currentThread().getStackTrace() (although you most likely will not if using a modern Oracle JVM), and the depth of the calling method isn't always length-2, it may be length-1 particularly in older versions of the Oracle JVM.
You can read more about this problem in this question.
To elaborate on what )some) people are telling you, this is MyFunctionFailedException, ofcourse it should be named something more sensible:
public class MyFunctionFailedException extends Exception {
public MyFunctionFailedException(String message, Throwable cause) {
super(message, cause);
}
}
Then your catch block becomes something like this.
try {
...
} catch (Exception e) {
throw new MyFunctionFailedException("extra message", e);
}
If you really want to rethrow a lower level exception, you should use multiple catch blocks. Be aware tho' that not all types of Exceptions necessarily has a constructor that let's you add a cause. And you really should think about why it makes sense for your method to let for instance an uncaught SQLException bubble up the call stack.

Null Pointer in catch block

I am using a try catch block to catch an exception. The console shows that it is throwing a null value. But it is not going to the catch block.
try {
System.out.println("Exception here "+SomeObject.getValue());
} catch (NullPointerException e) {
// TODO: handle exception
SomeObject so = new SomeObject();
}
SomeObject.setValue();
}
How could this be handled. Can I also use method level throws NullPointerException ?
It indeed would have went inside the catch block. There is another potential NullPointerException at the line (assuming you are trying to say)
so.setValue();
Having said that it is not advised to throw RuntimeException. It is better you handle NullPointerException in your code not through try/catch but through simple condition checks
it is a bad idea to catch UnChecked Exceptions, rather than catching NullPointerExcetpion, you can simple check for null values in an If condition.
if(SomeObject.getValue()!=null)
System.out.println(SomeObject.getValue());
You can put another try block inside catch
try {
doSomething();
} catch (IOException) {
try {
doSomething();
} catch (IOException e) {
throw new ApplicationException("Failed twice at doSomething" +
e.toString());
}
} catch (Exception e) {
}

Categories