Lambda in Java 8 launching Exception

3

I have the following problem.

I need to perform a process of updating the user and his group, and to make the change I search the user, validating if it exists and soon after, I look for the group checking if it exists, if any mistake happens I upload one new Exception reporting.

However, when I use orElseThrow of the group inside a lambda I get the following error from the IDE:

  

Unhandled exception: java.lang.Exception

Follow the code below:

    public UserDTO updateUser(UserDTO dto) throws Exception {
    if (dto.getId() == null) {
        throw new Exception("Usuario não informado corretamente para atualização.");
    }

    // buscando dados de usuario
    final Optional<UserEntity> user = repository.findById(dto.getId());
    user.ifPresent(u -> {
        u.setEmail(dto.getEmail());
        u.setStatus(dto.isStatus());

        // buscando referencia de grupo
        final Optional<GroupEntity> group = groupService.getGroup(dto.getGroupId());

        // grupo nao encontrado
        group.orElseThrow(() -> new Exception("Grupo não encontrado"));

        // grupo encontrado
        group.ifPresent(g -> {
            u.setGroupEntity(g);
        });

        repository.save(u);
    });

    // usuario nao encontrado
    user.orElseThrow(() -> new Exception("Usuario não encontrado"));

    return dto;
}
    
asked by anonymous 27.03.2018 / 23:48

2 answers

3

Lambdas and exceptions checked do not form a good mix. But before that, throws Exception and throw new Exception are bad programming practices.

You should launch and handle specific exceptions rather than generic exceptions.

In addition, you can use the exception to get rid of both null and Optional . Note that orElseThrow(...) returns the object encapsulated within Optional .

Try to do this:

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

public UserDTO updateUser(UserDTO dto) throws NotFoundException {
    if (dto.getId() == null) {
        throw new IllegalArgumentException(
                "Usuário não informado corretamente para atualização.");
    }

    // Busca referência de usuário. Lança exceção se não encontrado.
    final UserEntity u = repository
            .findById(dto.getId())
            .orElseThrow(() -> new NotFoundException("Usuário não encontrado"));

    // Busca referência de grupo. Lança exceção se não encontrado.
    final GroupEntity g = groupService
            .getGroup(dto.getGroupId())
            .orElseThrow(() -> new NotFoundException("Grupo não encontrado"));

    u.setEmail(dto.getEmail());
    u.setStatus(dto.isStatus());
    u.setGroupEntity(g);
    repository.save(u);

    return dto;
}
    
28.03.2018 / 00:11
1

The problem is here:

//...
user.ifPresent(u -> {
    //...
    group.orElseThrow(() -> new Exception("Grupo não encontrado"));
    //...
});
//...

When you use a lambda in this case, you are passing the method ifPresent a Consumer whose implementation of the accept method is the code between the keys. As in the signature of this method it is not defined that it can issue a checked exception , the compiler informs you of the error. To fix it, you should treat the checked exception within the lambda (which is not feasible in your case, since you want to throw the exception to indicate a problem).

This error does not occur with unchecked exceptions , since a method that throws them does not need to specify it in its signature. So they become good candidates to solve your problem.

You could create an exception that extends from RuntimeException to signal the error of an entity not found:

public class EntityNotFoundException extends RuntimeException { 
    public EntityNotFoundException(String message) {
        super(message);
    }
}

And throw the exception like this:

//...
user.ifPresent(u -> {
    //...
    group.orElseThrow(() -> new EntityNotFoundException("Grupo não encontrado"));
    //...
});
//...

A functional example of launching unchecked exceptions inside a lambda expression can be tested here . p>     

28.03.2018 / 00:27