0

I have a Symfony entity with @UniqueEntity annotation. I use it so I don't get double records in my database with the same email but I don't want to return to the user that the email is already in the database (privacy reasons).

How can I use @UniqueEntity but catch the error and return to the user a success message?

Controller code:

    public function register(Request $request, EntityManagerInterface $entityManager, TranslatorInterface $translator): Response
    {
        $success = false;

        $newsletter = new Newsletter();
        $form = $this->createForm(NewsletterType::class, $newsletter);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
                $newsletter = $form->getData();

                $entityManager->persist($newsletter);
                $entityManager->flush();

                $this->addFlash('success', $translator->trans('newsletter.signed_up'));

                return $this->redirectToRoute('landing');
        }

        return $this->render('landing/landing.html.twig', [
            'newsletter_form' => $form->createView(),
            'newsletter_success' => $success,
        ]);
    }
nass
  • 382
  • 1
  • 6
  • 19
  • Can you show the code, e.g. from your controller where you want to catch the error? – dbrumann May 25 '20 at 11:16
  • @dbrumann added, it's simple controller with just one form, nothing complicated – nass May 25 '20 at 11:51
  • 1
    All websites tell you that the username or email is already taken, so how the user will know that the email is already exists ? – hous May 25 '20 at 16:51
  • @hous but when you enter email on the reset password, for example, it doesn't say whether an account with that e-mail address is in a database for security/privacy reasons. That's what I want to achieve here. I don't want someone else other than the owner of the e-mail address know whether account exists / is subscribed to newsletter. – nass May 25 '20 at 17:43
  • for reset password , yes we don't say that the email exists or not but you can say "if the email exists you will recieve an email ...". – hous May 25 '20 at 17:51
  • and that's why I want to suppress `UniqueEntity` validation error but still validate that I don't send another recovery email (and the easiest way is with `UniqueEntity`). – nass May 25 '20 at 17:54
  • My question is, when a user try to register but the email exists, what will you say to him ? – hous May 25 '20 at 18:06
  • Does that really matters when it comes to the technical side of my question? "if the email exists you will recieve an email ..." – nass May 25 '20 at 18:49
  • @hous on the side note: I really dislike this “if an account is registered you will receive an email” kind of text. Now I don’t know if I’m registered or the email just didn’t arrive. But I still can always check if I registered or not using the registration form. – Mike Doe May 26 '20 at 08:45
  • I see it not logic to not say that the email exists when registration, but if you want do it I think you don't need to use UniqueEntity but in the registration function after form submitted you select one user by email sent in the form , if true so you redirect him to success page – hous May 26 '20 at 19:00

1 Answers1

0

Basically, two possibilities:

  1. Check if inserted email is already in DB performing an explicit query (keep @UniqueConstraint annotation in order to preserve data integrity).
  2. Wrap entity manager operation in try-catch block, as follows (check also this answer)

    try {
      $entityManager->persist($newsletter);
      $entityManager->flush();
    } catch (UniqueConstraintViolationException $e) {
      // you can check if the exception is raised by email field, somehow, or just "mask" with a general error
    }
    
DonCallisto
  • 29,419
  • 9
  • 72
  • 100