Should we throw exceptions ?

Is throwing an exception a good practice?   Problem is never throwing an exception. Problem is in catching and suppressing the exception. Let’s begin with a short example

public class CustomerDepartureInformation {
    // null values are legal
    private Map<String, String> valuesFromDB;

    private static Map<String, String> defaultValues;

    class CustomerNotFoundException extends Exception {
        public CustomerNotFoundException(String message) {
            super(message);
        }
    }

    public String getByKey(String key) {
        try {
            return getValueByKey(key);
        } catch (CustomerNotFoundException | RuntimeException ex ) {
            String defaultValue = defaultValues.get(key);
            valuesFromDB.put(key, defaultValue);
            return defaultValue;
        }
    }

    private String getValueByKey(String key) throws CustomerNotFoundException {
        if (valuesFromDB.containsKey(key)) {
            return valuesFromDB.get(key);
        } else {
            throw new CustomerNotFoundException( key + " is not present");
        }
    }
}

Now please focus on getValueByKey() method and ask your self: Should this method really need to throw an exception? This code is not wrong and throwing an exception seems okay but after Java 8 we can use Optional, here we go to the second version of this code

public class CustomerDepartureInformationV2 {
    // null values are legal
    private Map<String, String> valuesFromDB;

    private static Map<String, String> defaultValues;


    public String getByKey(String key) {

            Optional<String> value = getValueByKey(key);
            if (value.isPresent()) {
                return value.get();
            } else {
                String defaultValue = defaultValues.get(key);
                valuesFromDB.put(key, defaultValue);
                return defaultValue;
            }

    }

    private Optional<String> getValueByKey(String key) {
        if (valuesFromDB.containsKey(key)) {
            return Optional.of(valuesFromDB.get(key));
        } else {
            return Optional.empty();
        }
    }
}

What is the difference? Instead of throwing an exception, now we are using Optional.  If you focus on getValueByKey(String key) method, you will see how we are returning Optional.empty() which is more effective than the first version. Let’s jump to the third version

public class CustomerDepartureInformationV3 {
    // null values are legal
    private Map<String, String> valuesFromDB;

    private static Map<String, String> defaultValues;

    public String getByKey(String key) {
        if (valuesFromDB.containsKey(key)) {
            return valuesFromDB.get(key);
        } else {
            String defaultValue = defaultValues.get(key);
            valuesFromDB.put(key, defaultValue);
            return defaultValue;
        }
    }
}

This version is the shortest and the coolest version. As you can see we can do the same functionality without throwing an exception or using Optional. The lesson of this blog is clear; think twice before throwing an exception.

 

No Comments

Post a Comment

Comment
Name
Email
Website