method.invoke dynamic exception throwing - java

short Summary : I want to create a wrapper/Interceptor for our java clients making external call and we have a lot of different java clients so I don't want to map exception one by one.
public Object handleRequest(Object delegate, Method method, Object[] objects) {
Object result = null;
try {
result = method.invoke(delegate, objects);
// do some logic
} catch ( IllegalAccessException | IllegalArgumentException e) {
// do nothing
} catch (InvocationTargetException e) {
throw e.getCause(); //java: unreported exception java.lang.Throwable; must be caught or declared to be thrown
}
return result;
};
};
}
In the code above, what I would like to do is throw the exception that the delegate is throwing (which would be obtainable by getting e.getCause(), but it is throwable). Since we have many maaany clients, I want to avoid checking it with many if and else statements and checking with isInstanceOf() (or other variations of it). Is there a way for me to throw the whatever e.getCause() as type of that specific type programatically?

No. If you are handed an arbitrary Method, you can't make the caller know what particular type of exception that method throws. You can of course throw Throwable and just throw e.getCause(), but it sounds like that's what you don't want to do -- but there's no way around it given the rest of your design.
You could move away from reflection and use interfaces and method references, but it's not clear from the context how feasible that is.

Related

How to handle exceptions that you didn't expect even thought it is declared on the documentation?

When there are methods that throw exceptions and you know these exceptions will not be thrown, what should you do?
Many times I see people just logging the exception, but I wonder if there is a build in exception in java that means something like: "This exception should not have been thrown".
For example, imagine I have a code that calls StaticClass.method(someObject) and this method throws a SpecificException when someObject is not valid. What should you do in the catch block?
try {
StaticClass.method(someobject);
} catch (SpecificException e) {
// what should I do here?
}
If when calling the method you know for sure that it will not throw an exception because of previous checks you should throw a RuntimeException wrapping the SpecificException.
try {
StaticClass.method(someobject);
} catch (SpecificException e) {
//This is unexpected and should never happen.
throw new RuntimeException("Error occured", e);
}
Some methods already throw a RuntimeException when they fail to perform their purpose.
//Here we know for sure that parseInt(..) will not throw an exception so it
//is safe to not catch the RuntimeException.
String s = "1";
int i = Integer.parseInt(s);
//Here instead parseInt(..) will throw a IllegalArgumentException which is a
//RuntimeException because h is not a number. This is something that should
//be fixed in code.
s = "h";
i = Integer.parseInt(s);
RuntimeExceptions don't require a try/catch block and the compiler will not be mad at you for not catch them. Usually they are thrown where something in your app code is wrong and should be fixed. Anyway there are cases where catching a RuntimeException is useful.

Try Catch block works but test assertThrows fail (Junit 5)

I am trying to follow this tutorial JUnit 5: How to assert an exception is thrown?
I use Java 10, IntelliJ 2018 and Junit 5.
I make a calculator app that adds 2 fractions. It checks whether the input has 0 in the denominator.
When I run the test The exception Message get printed out "Undefined Math Expression" but my IDE says "Expected java.lang.Throwable to be thrown, but nothing was thrown." I think there is some problem with the scope of my code? I'm a newbie, please be kind. I provided the code and the test below:
public class Calculator {
public static int[] calculate (int firstNumerator, int firstDenominator, int secondNumerator, int secondDenominator) {
String exceptionMessage = "Undefined Math Expression";
int resultNumerator;
int resultDenominator;
int[] result = new int[2];
resultNumerator = (firstNumerator * secondDenominator) +
(secondNumerator * firstDenominator);
resultDenominator = firstDenominator * secondDenominator;
try {
if (resultDenominator == 0) {
throw (new Throwable(exceptionMessage));
} else {
result[0] = resultNumerator;
result[1] = resultDenominator;
}
} catch (Throwable e) {
System.out.println(e.getMessage());
}
return result;
}
}
The test:
class CalculatorTest {
#Test
void denominatorContainsZero() {
assertThrows(Throwable.class, () -> {
Calculator.calculate(0,0,0,0);
});
}
}
The misunderstanding here appears to be in what JUnit can actually see.
JUnit isn't magical: it's just plain old Java. It can't see inside your methods to see what they are doing. All it can see is what any other code can see when it executes a method: the return value and uncaught exceptions (as well as any side effects of the method, if they are visible to the calling code).
Your method here doesn't throw an exception from the perspective of a caller: internally, it throws the exception, but it catches and handles it.
If you want JUnit to test that an exception is thrown, you need to not catch that exception.
It is never (*) the right thing to do to throw an exception and then catch and handle it yourself. What's the point? You can simply do the thing you do to handle it, without throwing the exception. Exceptions are expensive to throw, because of the need to capture the entire stack trace.
Throwable is never (*) the right exception to throw. It's the exception "equivalent" of returning Object: it conveys no type information about the exception to the caller, who then either has to do a lot of work to try to handle it; or, more realistically, should just propagate it themselves. IllegalArgumentException is the right exception to throw here, if you actually needed to throw (and not catch) an exception.
Throwable is rarely the right thing to catch. Throwable is a supertype of both Exception and Error, so you might unintentionally catch an Error, like OutOfMemoryError, which shouldn't be caught because there is nothing reasonable to do except crash your program. Catch the most specific type you can; which also means that you should throw the most specific type you can (or, at least, a type appropriate to the abstraction).
(*) This is "never" as in "ok, there are a limited number of circumstances where it may be appropriate". But unless you understand what these are, don't.
The Throwable is catched by try catch block, so Junit can not access it. Try remove the try catch block.
You are not actually throwing exception, you are catching it. For this to work, you should remove try catch block.

NullPointerException not being caught

I am using Java reflection as such:
try {
method.invoke(someObject);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NullPointerException e) {
//Do something
}
method is retrieved from iterating through getMethods() from "Set<Method> getMethods = new HashSet<Method>(Arrays.asList(curObject.getClass().getMethods()))"
someObject is not null, but within the method call it makes a call to something that results in a NullPointerException.
However, the code still errors out with a NullPointerException with the stack trace pointing back to "method.invoke(someObject);".
Why doesn't the catch work? Has it something to do with reflection?
i think you should try this:
try
{
// your code may error occures !!
}
catch(NullPointerException e)
{
//do your work here
}
catch(InvocationTargetException e)
{
//do your work here
}
catch(IllegalAccessException e)
{
//do your work here
}
catch(IllegalArgumentException e)
{
//do your work here
}
catch(Exception e)
{
//do your work here
}
here all your Exceptions catch in multiple catch blocks.
If I read the stack trace correctly, it is not a NullPointerException being thrown, but a com.mapp.node.logging.exception.ConstructingFatalThrowableException with the message (and probably the cause) "java.lang.NullPointerException".
The first line of a NullPointerExcpetion stack trace would actually start with java.lang.NullPointerException.
To check this, you could just add ConstructingFatalThrowableException to your catch block.
That's not a NPE: it's a com.mapp.node.logging.exception.ConstructingFatalThrowableException thrown by some funky code instrumented to intervene when building NPEs.
Read the stack from bottom-up:
com.mapp.node.logging.exception.ConstructingFatalThrowableException: java.lang.NullPointerException
at com.mapp.server.util.ExceptionInstrumentationUtil.handleFatalThrowable(ExceptionInstrumentationUtil.java:212)
at com.mapp.server.util.ExceptionInstrumentationUtil.access$000(ExceptionInstrumentationUtil.java:32)
at com.mapp.server.util.ExceptionInstrumentationUtil$2.sample(ExceptionInstrumentationUtil.java:164)
at com.mapp.server.util.ExceptionInstrumentationUtil$2.sample(ExceptionInstrumentationUtil.java:160)
at com.google.monitoring.runtime.instrumentation.ConstructorInstrumenter.invokeSamplers(ConstructorInstrumenter.java:207)
at java.lang.RuntimeException.<init>(RuntimeException.java:52)
at java.lang.NullPointerException.<init>(NullPointerException.java:60)
The thread is at NullPointerException.java:60 where there is a call to java.lang.RuntimeException.<init> (ie. the superclass constructor) where (at RuntimeException.java:52) there's what the JVM is instrumented to think of as a call to com.google.monitoring.runtime.instrumentation.ConstructorInstrumenter.invokeSamplers (I believe it takes the place of a super()?).
Anyhow - your exception is thrown in ExceptionInstrumentationUtil.java:212.
The reason you are not catching the exception is that it's not a NullPointerException, but a com.mapp.node.logging.exception.ConstructingFatalThrowableException. This exception is being thrown with the message (which follows the exception's name) "java.lang.NullPointerException" and that's the source of confusion. Try to catch the ConstructingFatalThrowableException instead of the NPE and see if it works.
Also, note that you shouldn't be catching a NullPointerException. It is a RuntimeException and this group of exceptions usually indicates a programming error, in which case you shouldn't "handle" it, because if you knew to expect it, you should have avoided the error. See what the docs say:
Runtime exceptions represent problems that are the result of a
programming problem, and as such, the API client code cannot
reasonably be expected to recover from them or to handle them in any
way. Such problems include arithmetic exceptions, such as dividing by
zero; pointer exceptions, such as trying to access an object through a
null reference (...)
With this in mind, just avoid the NullPointerException. Check an example below:
if(var!= null) {
//Normal code here
}
else {
//Handle the null pointer here
}

How do i handle the exception in an own function that Java compiles again?

As mentionend in the Subject: Java forces me to return something, because the handling of the Exception is in an own function.
public String returnLel(String mattDamon) {
try {
trick(mattDamon); // The LelException could be thrown
return "lel";
} catch (LelException e) {
handleException();
}
}
public void handleException() {
throw new RuntimeException();
}
`
Your code will not compile because the compiler is not "clever" enough to know you are throwing a RuntimeException in handleException.
In order for your code to compile you can either:
directly throw new RuntimeException(); in your catch statement (ugly)
return null after invoking handleException(); (acceptable, but still kind of ugly)
add a finally statement to finalize your method and return null or whatever if some condition has not been met (recommended)
Also note that I'm assuming LelException extends RuntimeException, otherwise your catch statement won't compile.
Well it is up to you on how you will handle the situation.
If you are able to handle the exception by say logging it and just return null as most of the comments imply that is totally o.k.
Just consider that this situation could also mean that the method "returnLel" might not be the correct place to handle this exception but to let the caller decide what to do in this situation by "throwing it further" like so:
public String returnLel(String mattDamon) throws LelException{
trick(mattDamon); // The LelException could be thrown
return "lel";
}
This means if the caller calls your returnLel-Method he will have to try/catch the Exception (or throw it further up) and could in this case mean a better design because the caller will not receive null or a String' but aStringor aLeLException` instead
Move the return statement out of the try catch.
The try block should surround the part where an exception could be thrown, what the return statement not does.
Here the java tutorials for some basic knowledge about this topic:
The try Block
The catch Block
The finally Block

If a socket accept causes a exception, how can I find out the reason?

I'm creating a function that will do a socket accept and return 3 vales
0=really bad error happen exit thread
1=ok talk to the connection
=something happen, do another accept (time out).
I see the IOException has a GetCause meths that returns a throwable object.
this throwable object has a get cause method that returns a throwable, which has a getcuase method returning a throwable, seems like this would go on forever, keep getting another throwable object.
How can I get the reason the exception ant off?????
I could use get reason and a bunch of string compares, but this does not seem to reliable.
Ted
int GetClient()
{
try {
server.setSoTimeout(5*1);
connection=server.accept();
}
catch(IOException ec)
{
System.out.println(Thread.currentThread()+":"+ec.getMessage());
return 2; // for time out or something where we can try again
// return a zero saying we must stop erra o bad
}
return 1;
}
accept()
throws a variety of exceptions.
SocketTimeoutException extends IOException but you can 'catch' it before catching the general IOException. This will allow you to return the value suggesting you can try again.
Does this cover your 3 cases, Ok, IOException and Timeout?
If you're only interested in timeout exceptions then catch those exceptions separately. Most IO methods can potentially throw an IOException, but there are many different subclasses of IOException (which themselves have further subclasses) that you can catch and deal with separately.
eg.
try {
conn = server.accept();
} catch (SocketTimeoutException e) {
return 2;
} catch (IOException e) {
// socket exception will not be recaught
// even if return statement wasn't used
return 0;
}
return 1;
The getCause method is provided as when exceptions are created they can be created with string message, but also the exception that may have caused this exception to be thrown. Thus allowing catchers of the exception to see the full detail of what caused the exception.
eg.
public double addNumbers(String a, String b) {
try {
double i = Double.parseDouble(a);
double j = Double.parseDouble(b);
return i + j;
} catch (NullPointerException cause) {
throw new IllegalArgumentException(
"Arguments aren't allowed to be null", cause);
} catch (NumberFormatException cause) {
throw new IllegalArgumentException(
"One or more arguments weren't numbers", cause);
}
}
The above case is a little obtuse, but it demonstrates the principal that some exception may be caught (that maybe it might try to be recovered from) and then a new exception thrown with the original exception as the cause. Having a getCause method allows the caller to immediately see that the IllegalArgumentException was originally thrown in the addNumbers method (and that this is where the problem in the user code base is). However, by looking at the cause they will be able to see a more detailed message about by the argument was illegal (NumberFormatException includes the string that was trying to be parsed).

Categories