Search code examples
jsfexceptioncustom-validators

Custom validator throws ValidatorException, but it doesn't block form submit


I am trying to use a validator to check at the registration if the email already exists in the database. For this I write my form like this :

<h:form>
    ...
    <h:inputText id="email" class="form-control" value="#{usersBean.email}">
        <f:validator binding="#{existenceEmailValidator}"/>
    </h:inputText> 
    <h:message for="email"/>
    ...
</h:form>

I also have an ExistenceEmailValidator class :

package com.ml.validators;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import com.ml.service.UsersService;

@ManagedBean
@RequestScoped
public class ExistenceEmailValidator implements Validator {

    private static final String EMAIL_EXISTE_DEJA = "Cette adresse email est déjà utilisée";

    @ManagedProperty( "#{usersService}" )
    private UsersService        usersService;

    @Override
    public void validate( FacesContext context, UIComponent component, Object value ) throws ValidatorException {

        String email = (String) value;

        try {
            if ( usersService.existingMail( email ) ) {
                System.out.println( "It throws !" );
                throw new ValidatorException(
                        new FacesMessage( FacesMessage.SEVERITY_ERROR, EMAIL_EXISTE_DEJA, null ) );
            } else {
            }
        } catch ( Exception e ) {

        }
    }

    public UsersService getUsersService() {
        return usersService;
    }

    public void setUsersService( UsersService usersService ) {
        this.usersService = usersService;
    }

}

The problem is that when I try to submit the form, the Sysout in ExistenceEmailValidator print "It throws" when he has to so the Exception seems to be thrown corretly. However in every cases, the form is submitted and the user is registered in the database even if the email address already exists.

So, what is the problem with my validator ? Am I using it correctly ?

Thanks for your answers !


Solution

  • You're indeed correctly throwing a ValidatorException. But you're then immediately catching it and completely suppressing it with an empty catch block. See my comments below.

    try {
        if ( usersService.existingMail( email ) ) {
            System.out.println( "It throws !" );
            throw new ValidatorException(
                    new FacesMessage( FacesMessage.SEVERITY_ERROR, EMAIL_EXISTE_DEJA, null ) );
        } else {
        }
    } catch ( Exception e ) {
        // Here the ValidatorException is being caught.
        // And you're doing nothing with it.
        // So, code continues as if nothing exceptional happened.
    }
    

    Get rid of that try-catch. It doesn't make sense. Let the exception go so JSF can deal with it.

    if ( usersService.existingMail( email ) ) {
        System.out.println( "It throws !" );
        throw new ValidatorException(
                new FacesMessage( FacesMessage.SEVERITY_ERROR, EMAIL_EXISTE_DEJA, null ) );
    }