Lambda in Java 8 launching Exception

Asked

Viewed 825 times

3

I have the following problem.

I need to perform a user update process and your group, and to perform the change I perform the user search, validating if it exists and soon after, I look for the group checking if it exists, in case any error happens I raise a new Exception informing.

However, when I use the orElseThrow group within a lambda have the return of the following error by the IDE:

Unhandled Exception: java.lang.Exception

Follows 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;
}
  • You need to see the definition of ifPresent. I think it’s a Consumer, that does not have in its definition the exception release

2 answers

3


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

You should release and treat specific exceptions and not generic exceptions.

Also, you can use the exception to get rid of both the null how much of Optional. Note that the orElseThrow(...) returns the encapsulated object inside the Optional.

Try to do so:

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;
}
  • Thank you very much! I will follow the instruction on programming practice. Again, thank you very much!

  • @You’re welcome to join us. I’m happy to help. ;)

1

The problem is here:

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

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

This error does not occur with unchecked exceptions, since a method that launches them, you do not need to specify it in your 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 cast the exception this way:

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

A functional example of the launch of unchecked exceptions within a lambda expression can be tested here.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.