Continue the flow after throwing exception - java

In my use case, I am looping across a map and checking whether a particular key is present in a list. If it is present then I have to trow and exception otherwise continue with the execution.
Map<A,B> myMap = new HashMap<A,B>();
//code to populate values in myMap
...
...
List<A> myList = new ArrayList<A>();
//code to populate values in myList
...
...
for(Map.Entry<A,B> eachElementInMap:myMap.entrySet()){
if(myList.contains(eachElementInMap:myMap.getKey())){
//throwing exception
throw new MyCustomizedException("someString");
}
}
//code continues
...
....
In the above example, if there are 3 elements in the map(myMap) in which 1 key is present in the list(myList), I want to throw the exception for one and it should continue executing other lines of code for the rest two. Am I using a wrong design to achieve this? Any help or suggestion is appreciated! Thanks

Typically once you throw an exception, you are saying that the current line of execution should terminate, rather than continue. If you want to keep executing code, then maybe hold off on throwing an exception.
boolean fail = false;
for (Map.Entry<A,B> eachElementInMap:myMap.entrySet()) {
if (myList.contains(eachElementInMap:myMap.getKey())) {
// throw an exception later
fail = true;
}
}
if (fail) {
throw new MyCustomizedException("someString");
}

You can also create an exception object at a different location from where you throw it. This idiom will be useful in cases where the exception message is not just "someString", but needs to be constructed from data obtained from the object being iterated over.
Optional<MyCustomizedException> exception = Optional.empty();
for (Map.Entry<A, B> eachElementInMap:myMap.entrySet()) {
if (myList.contains(eachElementInMap.getKey())) {
// Create an exception object that describes e.g., the missing key(s)
// but do not throw it yet.
if( exception.isPresent() ) {
exception.get().addToDescription( /* Context-sensitive information */ );
}
else {
exception = Optional.of(
new MyCustomizedException( /* Context-sensitive information */));
}
}
}
if( exception.isPresent() ) {
throw exception.get();
}
If the only data stored in the exception is a string, an equivalent effect can be achieved by accumulating problem descriptions in a StringBuilder, but for cases where more interesting data needs to go into the exception object, building as you go might be an option worth considering.

You can split it into two lists,failList and successList. and do it.
This is clearer
failList = myMap.entrySet().stream().filter(p->myList.contains(p.getKey())).collect(Collectors.toList());
successList = myMap.entrySet().stream().filter(p->!myList.contains(p.getKey())).collect(Collectors.toList());
failList.forEach(p -> {
// fail code
});
successList .forEach(p -> {
// success code
});

why not use if...else instead of try catch ? error just means that's a mistake. if you afraid that makes some mistakes what you don't know. you can use throw error.
anyway, it should not be used when the program is running as you wish

Related

How check if an Attribute(object) is null in Java

I need specific data for a report, then I gettin all information from a parent object
Object1
It has many attributes, object attributes
Object11, Object12, Object13, attr1, attr2...
The attributes has many attributes too
Object111, Object131, Object132,..
by now I got 5 level data attributes.
When I send information to my report it says, Error: cause:null
object1.getIdObject11().getIdObject111().getDescription;
It trows error because Object111 is null
I tried using
object1.getIdObject11().getIdObject111().getDescription==null?'':object1.getIdObject11().getIdObject111().getDescription;
but it only verify if description is null, and throws the same error
Then I tried to verify Object
if(object1.getIdObject11().getIdObject111() == null) {
var = object1.getIdObject11().getIdObject111().getDescription;
} else {
var = "";
}
But when Object11 is null, it throws same error.
I don't think its a good way doing this for each attribute (have to get like 30 attributes)
if(object1.getIdObject11()!=null) {
if(object1.getIdObject11().getIdObject111()!=null) {
if(object1.getIdObject11().getIdObject111().getIdObject1111()!=null) {
//...
}
}
}
I want to verify if is there a null object and set '' (blank) if it is, with no such a large code(because the gotten params are set inside a report, mixed with letter).
reportline1 = "Area: "+object1.getIdObject11().getIdObject111().getName;
You code breaks Demeter's law. That's why it's better to refactor the design itself.
As a workaround, you can use Optional
var = Optional.ofNullable(object1)
.map(o -> o.getIdObject11())
.map(o -> o.getIdObject111())
.map(o -> o.getDescription())
.orElse("")
The way I would probably do this to extend the functionality of the code easily in the future might take a bit of writing in the beginning but will be easily usable forever.
I would create a new method in your parent class called hasNull that returns a boolean like so:
public boolean hasNull()
{
boolean hasANull = false;
//Call another hasNull() inside of object11 which in turns calls hasNull() in object111 etc.
//If any of the calls return with a true/null value set hasANull to true
return hasANull;
}
This in turn checks to see if the current objects it contains are null. If one of the class variables is another custom class you created you can then add another hasNull into that one and keep going until you get to the lowest level where you can do a specific operation when the value is null such as set it to "".
After implementing this you will be able to just be able to use it like this any time you need it:
if (!object1.hasNull())
{
//Do whatever you want if there are no null values
}
else
{
//Do whatever you want if there is a null value
}
You can also make this a void method if you only want it to toggle the values on the lowest level, and do not need to do anything in either case.
I prefer the solution that gave dehasi.
But you can also do something like that:
getOrElse(() -> object1.getIdObject11().getIdObject111().getDescription(), "")
Where getOrElse is:
public static <T> T getOrElse(Supplier<T> getter, T elseValue) {
try {
return getter.get();
} catch (Exception e) {
// log or do something with it
}
return elseValue;
}
It may be controversial becaouse you use Exception to do this.
You can use this code to check if your object has a null attribute, the object is myclass;
for (Field f : myclass.getClass().getDeclaredFields()) {
f.setAccessible(true);
try {
if (Objects.isNull(f.get(myclass))) {
isLineContainsNull = true;
}
} catch (Exception e) {
log.error(e.getMessage());
}
}

Handle exception's causes differently

In one of my software, I'm using a library that is basically a protocol implementation. The library is structured according to the five first OSI layers (physical to session).
I have to use the session layer with this interface
public interface ReadSession {
Iterable<byte[]> read(boolean fromStart, byte dataset, int nbData) throws SessionException;
}
Now my problem is that, according to the inner (or inner's inner, etc.) cause I need my software to behave differently.
Examples (> represents the inner cause relation):
If SessionException > IOException > ... then I should abort all the communications
If SessionException > TransportException > NetworkException > ... then I should log the exception and proceed with the next communication
If SessionException > TransportException > GatewayException > ... then I should warn the user that there's a problem with its gateway
But all what I have at the moment is a single catch
catch(SessionException e) {
//How to handle this problematic properly ?
}
I feel myself not comfortable with a fixed number of call to getCause() because:
of the lot of null checks involved
I rely on the implementation details of the library (leaky abstraction) and if these change in the future I'm screwed
Has anyone already faced such a situation and want to share his knowledge about how to handle it as cleanly as possible ?
One approach here is to create a List of the causes in your single catch block.
For example:
catch (SessionException t)
{
List<String> causeList = new ArrayList<>();
do
{
causeList.add(t.getClass().getName());
t = t.getCause();
} while(t != null);
}
Then what you can do is compare the causeList with a set of predefined cause lists that you hardcode. When you find that the causeList equals one of your predefined lists, then you take the appropriate path of code.
A predefined List can look something like:
final List<String> ABORT_LIST = new ArrayList<String>
(Arrays.asList("com.package.SessionException", "java.io.IOException"));
Then, after you build the causeList in the catch block, you can do something like this:
if (causeList.equals(ABORT_LIST))
{
System.out.println("Aborting...");
}
I ended up using something like this:
catch(SessionException e) {
Throwable cause = e.getCause();
while(cause != null) {
if(cause instanceof NetworkException.class) {
//Trigger some logic
}
else if(...)
cause = cause.getCause();
}
}

Breaking a method before having a return value

Is there any solution i can break a running method which is supposed to return an int[] or whatever but !without! any return value.
I thought that might work with some exception but i didn't find a propper way. To be more specific i want something which tries to find out if a certain field of an object was set and if yes return it and if no returns a message which tells me that the input wasn't made so far.
something like this:
public int[] returnArray(){
if(array_was_set==true) return the array;
else show message that it wasnt set and quit the method without any return value;
}
One way of doing that, return null and make the caller decide , if the caller gets a nun-null (or maybe a non-empty) array it will process it in some way and if the caller get an empty or null array it could print a message.
I would recommend against using exceptions as a substitute for return values see this question to know more about when to throw an exception.
There are three options to choose from, depending on your scenario:
Use return value of null (and document it)
Throw an exception with a detailed message. I would use this version only for exceptional cases such as illegal API usage or a logical error situation(bug).
Return a wrapper class, containing both a return value and some other message, when relevant
Edit: Another 2 options:
Use polymorphism - Return type can be Result, and concrete subclasses can be NoResult and DataResult.
Instead of returning null, return a constant value defined as:
static final NO_RESULT = new int[0];
Later you can check the returned value against it (using == condition).
You should be able to do it by raising an exception. Just use the message in the exception's constructor.
However, exceptions are relatively expensive and if this isn't really an error condition you should consider doing something else, such as returning null to indicate there is nothing to return.
Yes better way is use Exception
example
public static void main(String[] args) {
try {
new Result().returnArray(false) ;
} catch (Exception e) {
}
}
.
public int[] returnArray(boolean input) throws Exception {
if(input) {
return new int[]{1};
}
else {
System.out.println("Not match");
throw new Exception();
}
}
When you declare in the method signature that it is returning a data type then it must have a return statement which returns that specific type value. Otherwise you will get compile-time error.
The only exception when a method can avoid return statement even though it has return type is when there is an infinite loop or an exception is thrown. Otherwise return statement is compulsory.
Coming to your question, you can easily achieve what you are doing. If you want to terminate at a particular point as per your requirement just say,
return null;
It will work for all the data types except for primitive types in which case you need to do type casting to Wrapper class types appropriately.
public int[] returnArr() {
if(some condition)
return SomeIntArray;
else
return null;
}
public int returnInt() {
if(some condition)
return 2;
else
return (Integer)null;
}

Chained Exceptions initCause(), is this correct?

I have a method:
public void SomeDataMethod() throws BadDataException {
try {
// do something
} catch(IOException e) {
throw new BadDataException("Bad data",e);
} finally {
// do something regardless of above
}
}
And now for example some code will invoke this method, and I want to see all failures which happened in this method,
so how can I do it by using initCause()? Or maybe is there any other way to do this? And if I use initCause():
1) will I get all exceptions which were catch or the last one?
2) and What form do I get them / it?**
When you call an Excepion Constructor with the throwable attached, like you have the e as part of the new BadDataException("Bad data",e); then the result is effectively the same as:
BadDataException bde = new BadDataException("Bad data");
bde.initCause(e);
This is to keep compatibility with earlier Java versions which did not have the initCause concept.
Not all exceptions support adding the cause as part of the constructor, and for those exceptions you can initCause it.
note that you can only initCause an exception once, and initializing it with 'null' cannot later be changed:
BadDataException bde = new BadDataException("Bad data", null);
// this will fail.....
bde.initCause(e);
To get the cause of an exception, you call... getCause(). In this case, this method will return the IOException that you wrapped inside your BadDataException. It can't return more that one exception, since you can only wrap one exception.

Java Null Reference Best Practice

In java, Which of the following is the more "accepted" way of dealing with possibly null references? note that a null reference does not always indicate an error...
if (reference == null) {
//create new reference or whatever
}
else {
//do stuff here
}
or
try {
//do stuff here
}
catch (NullPointerException e) {
//create new reference or whatever
}
The answers already given are excellent (don't use exceptions for control flow; exceptions are expensive to throw and handle). There's one other important reason specifically not to catch NullPointerException.
Consider a code block that does the following:
try {
reference.someMethod();
// Some other code
}
catch (NullPointerException e) {
// 'reference' was null, right? Not so fast...
}
This might seem like a safe way to handle nullity of reference ...but what if reference was non-null and someMethod() raised NPE? Or what if there was a NPE raised elsewhere in the try block? Catching NPE is a surefire way to prevent bugs from being found and fixed.
Catching exceptions is relatively expensive. It's usually better to detect the condition rather than react to it.
Of course this one
if (reference == null) {
//create new reference or whatever
}
else {
//do stuff here
}
we shouldn't rely on exception for decision making, that aren't given for that purpose at all, also they are expensive.
Well If you aren't making decision and just verifying for initialized variable then
if (reference == null) {
//create new reference or whatever
}
//use this variable now safely
I have seen some auto code generator wraps up this thing in accessors/getter method.
I think in general an exception should be reserved for exceptional circumstances - if a null reference is sometimes expected, you should check for it and handle it explicitly.
From the answers its clear that catching an exception is not good. :)
Exceptions are definitely not free of cost. This might help you to understand it in depth. .
I would also like to mention an another practice while comparing your object with a known value.
This is the traditional way to do the job: (check whether the object is null or not and then compare)
Object obj = ??? //We dont know whether its null or not.
if(obj!=null && obj.equals(Constants.SOME_CONSTANT)){
//your logic
}
but in this way, you dont have to bother about your object:
Object obj = ???
if(Constants.SOME_CONSTANT.equals(obj)){ //this will never throw
//nullpointer as constant can not be null.
}
The first one, throwing exceptions is a costly operation.
The first form:
if (reference == null)
{
//create new reference or whatever
}
else
{
//do stuff here
}
You should not use exceptions for control flow.
Exceptions are for handling exceptional circumstances that would not normally occur during normal operating conditions.
You should use exception catching where you do not expect there to be an error. If something can be null, then you should check for that.
maybe the try catch approach will start making sense in this situation when we can start doing
try {
//do stuff here
}
catch (NullPointerException e) {
//create new reference or whatever
retry;
}
This is related to your style of development, if you are developing code using "safe" style you have to use
if(null == myInstance){
// some code
}else{
// some code
}
but if you do not use this style at least you should catch exception, but in this case it NullPointerException and I think preferably to check input parameters to null and not wait to throwing exception.
Since you asked for Best Practices, I want to point out that Martin Fowler suggests to introduce a subclass for null references as best practice.
public class NullCustomer extends Customer {}
Thus, you avoiding the hassle of dealing with NullPointerException's, which are unchecked. Methods which might return a Customer value of null, would then instead return a NullCustomer instead of null.
Your check would look like:
final Customer c = findCustomerById( id );
if ( c instanceof NullCustomer ) {
// customer not found, do something ...
} else {
// normal customer treatment
printCustomer( c );
}
In my opinion, it is permissible in some cases to catch a NullPointerException to avoid complex checks for null references and enhance code readability, e.g.
private void printCustomer( final Customer c ) {
try {
System.out.println( "Customer " + c.getSurname() + " " + c.getName() + "living in " + c.getAddress().getCity() + ", " + c.getAddress().getStreet() );
} catch ( NullPointerException ex ) {
System.err.println( "Unable to print out customer information.", ex );
}
An argument against it is that by checking for individual members being null, you can write a more detailed error message, but that is often not necessary.

Categories

Resources