Loop continuing even after hitting return statement - java

I have the following method where I wan to keep checking if a nested exception matches an IndexOutOfBoundsException unless the nested exception is the same as the previous one.
It seems to do the right thing where in my test, the first exception
is of type NullPointerException thus moving on to the next. The next exception is as expected, an IndexOutOfBoundsException.
When this happens I want to return true which I expect to break me out of the loop.
It seems to be happening as expected where I do land on 'return true'. But after that, the loop keeps going.
What am I missing. How is it keeping on going even after returning true?
public boolean test(Throwable throwable) {
do {
if(throwable instanceof IndexOutOfBoundsException) {
return true; // I do land here thus expecting to get out of loop and this method.
}
this.test(throwable.getCause());
} while (throwable.getCause() != throwable);
return false;
}
The test against it simulating nested exception.
#Test
void testWithNestedException() {
NullPointerException nullPointerException = new NullPointerException();
IndexOutOfBoundsException indexOutOfBoundsException = new IndexOutOfBoundsException();
Throwable nestedException = nullPointerException.initCause(indexOutOfBoundsException);
assertTrue(someClass.test(nestedException));
}

You are mixing recursion with looping. Here, a simple loop that updates the exception being tested should do the trick:
public boolean test(Throwable throwable) {
Throwable t = throwable;
do {
if (throwable instanceof IndexOutOfBoundsException) {
return true;
}
t = t.getCause();
} while (t.getCause() != t);
return false;
}

You are creating recursion with this call and don't use the return code from this call.
this.test(throwable.getCause());
I think you wanted to do:
throwable = throwable.getCause();

As #Mureinik points out, you are mixing recursion and iteration and doing neither correctly. A (correct) recursive version would be:
public boolean test(Throwable throwable) {
if (throwable == null) {
return false;
} else if (throwable instanceof IndexOutOfBoundsException) {
return true;
} else {
return test(throwable.getCause());
}
}
In my opinion, a recursive version is easier to understand than an iterative one, but others may disagree.
With the recursive version, there is the theoretical problem that sufficiently deeply nested exceptions could lead to a stack overflow. Getting that to happen in practice would require some rather contrived (i.e. unrealistic) code, so it should be safe to ignore this.

Related

Want to print an error message in case of exception, but have to return a value from method

I have a method that receives a string and then returns an enum. I want to print an error message if the string matches none of the regexes. The only problem is that the method requires me to return something. I could return null, but that means I have to check for null once the enum has been returned. I was wondering if there was an easy and more conventional way to handle this? I want to catch the exception as I don't want the program to crash.
public static Direction getDirection(String direction) {
try {
direction = direction.toLowerCase();
if (direction.matches("go\s+[n]|go\s+north|north|[n]")) {
return NORTH;
} else if (direction.matches("go\s+[s]|go\s+south|south|[s]")) {
return SOUTH;
} else if (direction.matches("go\s+[w]|go\s+west|west|[w]")) {
return WEST;
} else if (direction.matches("go\s+[e]|go\s+east|east|[e]")) {
return EAST;
} else {
throw new IllegalArgumentException();
}
}
catch (IllegalArgumentException unknownCommand) {
System.out.println("Unknown Command");
}
}
```
I would go for null. Java does not guarantee that a given object is not null at a given point in time, so you actually need to do null-checks frequently if you really want to avoid NPEs at all costs.
If you definitely want to avoid null, then I would go with a new Enum value for Direction. Something like UNDEFINED or UNDETERMINED or UNKNOWN or INVALID.

Java: Implementing search function. Return fails if not found

I am trying to implement a search function. The function returns an object of type Prestamo if it finds a matching element. The function shouldn't return anything if nothing is found, but I get (of course) an error complaining about a missing return statement. How is this kind of problem solved? I guess Try-catch could be my friend for this, but I am struggling to understand that syntax.
This is my code:
public Prestamo buscarPrestamoPorUUID(UUID idPrestamo, ArrayList<Prestamo> listaBuscar) {
Iterator<Prestamo> it = listaBuscar.iterator();
Prestamo esteElemento;
while (it.hasNext()) {
esteElemento = it.next();
if (esteElemento.getActivo() && esteElemento.getIdPrestamo().equals(idPrestamo)) {
return esteElemento;
}
}
}
In Java, the control over a method must end in one of two ways:
A return statement, which returns an object of the type declared in the method signature OR null
A thrown exception (if the Exception does not extend RuntimeException, it must be declared in the method signature).
To resolve your compilation error, you need to do one of the two. If you want to do the former, it'd probably look something like this:
public Prestamo buscarPrestamoPorUUID(UUID idPrestamo, ArrayList<Prestamo> listaBuscar) {
Iterator<Prestamo> it = listaBuscar.iterator();
Prestamo esteElemento;
while (it.hasNext()) {
esteElemento = it.next();
if (esteElemento.getActivo() && esteElemento.getIdPrestamo().equals(idPrestamo)) {
return esteElemento;
}
}
return null;
}
Just be sure that the logic that invokes this method is prepared to handle null.
If you want to do the second, you'd do something like this:
public Prestamo buscarPrestamoPorUUID(UUID idPrestamo, ArrayList<Prestamo> listaBuscar) {
Iterator<Prestamo> it = listaBuscar.iterator();
Prestamo esteElemento;
while (it.hasNext()) {
esteElemento = it.next();
if (esteElemento.getActivo() && esteElemento.getIdPrestamo().equals(idPrestamo)) {
return esteElemento;
}
}
throw new RuntimeException("Didn't find an entity with the provided UUID!");
}
I personally prefer the former to the latter. It's a perfectly-valid use of null, and it makes the method easier to use than having to worry about uncaught exceptions. Regardless, note how that either implementation reaches a return or throw statement eventually. That's what your compiler checks for.
(P.S.: You can replace your while-loop with a for-each loop for code clarity.)
You could have it return null when no match is found. This would require the caller of the buscarPrestamoPorUUID() method to do a test for null and handle appropriately using a try/catch or some other way to handle it. ie:
Prestamo test = buscarPrestamoPorUUID(someID, someList);
if(test == null)
{ /* handle no match found */ }
else
{ /* handle result found */ }

Returning null AFTER a try-catch block

I'm having some trouble understanding the implications of the code in my accessor method below. Eclipse's compiler is requiring that I have a return statement after my try-catch block. Does this mean that my getter method will always return null or will it return the item I'm trying to retrieve if it int i doesn't need to be caught by the IndexOutOfBoundsException?
public T get(int i)
{
try
{
return bag[i];
}
catch(IndexOutOfBoundsException e) //if(logiSize < i+1)
{
System.out.println("Collection has fewer items than the index you entered!");
System.out.println("Returning null"); //or should I...?
}
return null;
}
Can anyone help me understand the implications here? Thanks so much!
Your method will return bag[i] unless you have an IndexOutOfBoundsException exception executing the return statement. In that case, they exception is caught, and since you're not throwing another exception inside the catch black. The method will proceed to return null.
If you only need to check for bounds, you could do this:
public T get(int i, T[] bag) {
if(i < bag.length) {
return bag[i];
}
return null;
}

Is it possible to stop try catch from returning null

If someone calls my method, I want to defensively deal with the problem. Usually I just return null.
I decided to implement a try catch but it looks like I just end up returning null anyway.
Can I write my try catch in such a way that at the end of method it doesn't return null?
Sample code, using peek on a Stack class.
public T peek()
{
T temp = null;
try
{
temp = array[size];
}
catch(Exception e)
{
}
return temp;
}
When called with an empty stack. It will return null.
So should I even bother with the try catch for this kind of case? I am tempted to do this:
if(isEmpty())
return null;
If the stack is not empty I want to return the element. If the stack is empty then can I avoid returning null if I use the try-catch?
This is how I would approach the problem. By throwing an exception in the peek function, putting the duty of handling that exception in the caller. Why? Because I want an error to cause an explosion as big as possible. The peek method also became smaller. Also as you already agree on, returning null is lame.
public T peek() throws IndexOutOfBoundsException
{
return array[size];
}
and
try
{
T top = thestack.peek();
/* Do something with that object */
}
catch(IndexOutOfBoundsException e)
{
/* Do something else */
}
The method has to return something or throw an Exception. If you have an unbounded generic type, then things like null object patterns can't be used, so the options are returning null, returning something that contains T like Optional<T>, or throwing an Exception.
If you don't like the safety of null, you can use Optional, either from Java 8 or a library. Checked exceptions have a similar safety but are inappropriate here.
It's hard to imagine the array[size] throwing an Exception, unless array is null or size is outside the length of array. So, you could do something like this -
if (array != null && array.length > size) {
return array[size - 1]; // assuming your size starts at 1
}
return null; // need to return something, if not null you need an option type.
Edit
Or, using an Option monad - and something like,
if (array != null && array.length > size) {
return new Some<T>(array[size - 1]); // assuming your size starts at 1
}
return new None<T>();

How can I loop through Exception getCause() to find root cause with detail message [duplicate]

This question already has answers here:
Java - find the first cause of an exception
(12 answers)
Closed 3 years ago.
I am trying to call saveOrUpdate() in hibernate to save data. Since columns have unique index, so its throws ConstraintViolationException when I look through via Eclipse debugger.
Since root cause could be different for different exception while inserting data to table.
I wanted to know, how can I loop / traverse through getCause() to check what is the root cause of exception and its message.
Update:
Thanks everyone for your kind response, thing is I want output like in below image:
I need to access detailMessage field.
(I am really sorry If could not make my question more clear.)
Thanks.
The Apache ExceptionUtils provide the following method:
Throwable getRootCause(Throwable throwable)
as well as
String getRootCauseMessage(Throwable th)
I normally use the implementation below instead of Apache's one.
Besides its complexity, Apache's implementation returns null when no cause is found, which force me to perform an additional check for null.
Normally when looking for an exception's root/cause I already have a non-null exception to start with, which is for all intended proposes is the cause of the failure at hand, if a deeper cause can't be found.
Throwable getCause(Throwable e) {
Throwable cause = null;
Throwable result = e;
while(null != (cause = result.getCause()) && (result != cause) ) {
result = cause;
}
return result;
}
Using java 8 Stream API, this can be achieved by:
Optional<Throwable> rootCause = Stream.iterate(exception, Throwable::getCause)
.filter(element -> element.getCause() == null)
.findFirst();
Note that this code is not immune to exception cause loops and therefore should be avoided in production.
Are you asking for something like this?
Throwable cause = originalException;
while(cause.getCause() != null && cause.getCause() != cause) {
cause = cause.getCause();
}
or am I missing something?
Guava's Throwables provides the following methods:
Throwable getRootCause(Throwable throwable)
as well as
String getStackTraceAsString(Throwable throwable)
In APACHE; the implementation is like below.
The highlight is list.contains(throwable) == false
public static Throwable getRootCause(final Throwable throwable) {
final List<Throwable> list = getThrowableList(throwable);
return list.size() < 2 ? null : (Throwable)list.get(list.size() - 1);
}
public static List<Throwable> getThrowableList(Throwable throwable) {
final List<Throwable> list = new ArrayList<Throwable>();
while (throwable != null && list.contains(throwable) == false) {
list.add(throwable);
throwable = ExceptionUtils.getCause(throwable);
}
return list;
}
} catch (Exception ex) {
while (ex.getCause() != null)
ex = ex.getCause();
System.out.println("Root cause is " + ex.getMessage());
}
Were you expecting something more complicated?
Try this, you can put this function in a kind of Util class:
public static Throwable getRootException(Throwable exception){
Throwable rootException=exception;
while(rootException.getCause()!=null){
rootException = rootException.getCause();
}
return rootException;
}
Example of usage :
catch(MyException e){
System.out.println(getRootException(e).getLocalizedMessage());
}
Source : How to get the root exception of any exception
Recursively:
public static Throwable getRootCause(Throwable e) {
if (e.getCause() == null) return e;
return getRootCause(e.getCause());
}

Categories