Joy
Joy

Reputation: 4483

Exception handling in Function interface

I am new to Function interface in Java 8. This question is related to Issue in abstracting common code using function interface. Getting idea from this I have written like below:

  public void act(Input1 input) throws NonRetriableException, InvalidInputException {

    Function<UpdateTaskInput, Boolean> func = item -> {
        try {
            activityManager.update(item);
            return true;
        } catch (InterruptedException | JSONException e) {

            throw new NonRetriableException(e);
        } catch (LockUnavailableException e) {

            throw new NonRetriableException(e);
        }
    };

    try {
        lockManager.executeWithLock(input.getTaskID(), input, func);
    } catch (LockUnavailableException e) {
        log.error("{}",e);
        throw new NonRetriableException(e);
    }
   }

and:

 public void perform()
    throws AutoAllocationException {

     Function<UpdateTaskInput, Boolean> func = item -> {
        try {
            activityManager.allocateTask(item);
            return true;
        } catch (AutoAllocationException ex) {
            log.error("{}",ex);
        }
        return false;
    };

    try {
        lockManager.executeWithLock(input.getTaskID(), input, func);
    } catch (LockUnavailableException e) {
        log.error("{}",e);
    }
  }

executeWithLock() in LockManager is as follows:

 @Override
 public <T,R> R executeWithLock(String lockName, T input, Function<T,R> func) throws LockUnavailableException {
    LockItem lockItem = acquireLock(lockName);
    R output = func.apply(input);
    releaseLock(lockItem); 
    return output;
}

Now my question is:

In executeWithLock() function do I have to capture all the exceptions, I mean should I handle exception from func.apply(). I want to know this because, releaseLock call I should do always irrespective of the fact exception has occurred or not.

Upvotes: 1

Views: 250

Answers (1)

LuCio
LuCio

Reputation: 5183

If act throws an exception your LockItem lockItem will not be released in executeWithLock. Therefore it is recommended to used the try-finally statement when working with Locks:

public <T, R> R executeWithLock(String lockName, T input, Function<T, R> func) throws LockUnavailableException {
    LockItem lockItem = acquireLock(lockName);
    try  {
        R output = func.apply(input);
        return output;
    } finally {
        releaseLock(lockItem);
    }
}

Another point:
Since act is throwing a NonRetriableException in a Function which does not declare any Exception that implies NonRetriableException extends RuntimeException. But the following try-catch-block does only catch exceptions of type LockUnavailableException. Exceptions of type NonRetriableException will not be catched and therefore not handled (logged). They will be propagated to the caller of act which is executeWithLock. This shows again the significance of the first point.

Upvotes: 2

Related Questions