diff --git a/support-frontend/app/actions/CustomActionBuilders.scala b/support-frontend/app/actions/CustomActionBuilders.scala index c9af5c39d9..8cdd023345 100644 --- a/support-frontend/app/actions/CustomActionBuilders.scala +++ b/support-frontend/app/actions/CustomActionBuilders.scala @@ -72,6 +72,7 @@ class CustomActionBuilders( emailProviderRejectedCode, invalidEmailAddressCode, recaptchaFailedCode, + emailAddressAlreadyTakenCode, ) if (result.header.status == 500) { if (!ignoreList.contains(result.header.reasonPhrase.getOrElse(""))) { diff --git a/support-frontend/app/controllers/CreateSubscriptionController.scala b/support-frontend/app/controllers/CreateSubscriptionController.scala index 79e5d8e278..338f819de3 100644 --- a/support-frontend/app/controllers/CreateSubscriptionController.scala +++ b/support-frontend/app/controllers/CreateSubscriptionController.scala @@ -233,10 +233,14 @@ class CreateSubscriptionController( ) } - private def mapIdentityErrorToCreateSubscriptionError(identityError: IdentityError) = + private def mapIdentityErrorToCreateSubscriptionError(identityError: IdentityError): CreateSubscriptionError = identityError match { case EmailProviderRejected(_) => RequestValidationError(emailProviderRejectedCode) case InvalidEmailAddress(_) => RequestValidationError(invalidEmailAddressCode) + // We're mapping this to a ServerError because it shouldn't ever happen, but sometimes does. Even though we + // asked identity (in getOrCreateIdentityUser) whether the user exists first, sometimes we get an answer of no + // back but then attempting to create returns this error. + case EmailAddressAlreadyTaken(_) => ServerError(emailAddressAlreadyTakenCode) case OtherIdentityError(message, description, endpoint) => endpoint match { case Some(GuestEndpoint) => ServerError(s"Identity error calling /guest: $message; $description") @@ -345,6 +349,14 @@ class CreateSubscriptionController( ), body = writeable.toEntity(err.message), ) + case ServerError(code) if code == emailAddressAlreadyTakenCode => + Result( + header = new ResponseHeader( + status = INTERNAL_SERVER_ERROR, + reasonPhrase = Some(emailAddressAlreadyTakenCode), + ), + body = writeable.toEntity(emailAddressAlreadyTakenCode), + ) case _: ServerError => InternalServerError } diff --git a/support-frontend/app/models/identity/responses/IdentityErrorResponse.scala b/support-frontend/app/models/identity/responses/IdentityErrorResponse.scala index 79cc4b9ed6..68fc7a6f9a 100644 --- a/support-frontend/app/models/identity/responses/IdentityErrorResponse.scala +++ b/support-frontend/app/models/identity/responses/IdentityErrorResponse.scala @@ -28,6 +28,7 @@ object IdentityErrorResponse { implicit val reads: Reads[IdentityErrorResponse] = Json.reads[IdentityErrorResponse] val emailProviderRejectedCode = "email_provider_rejected" val invalidEmailAddressCode = "invalid_email_address" + val emailAddressAlreadyTakenCode = "email_address_already_taken" sealed trait IdentityError { def endpoint: Option[IdentityEndpoint] @@ -35,6 +36,7 @@ object IdentityErrorResponse { this match { case EmailProviderRejected(_) => EmailProviderRejected(Some(e)) case InvalidEmailAddress(_) => InvalidEmailAddress(Some(e)) + case EmailAddressAlreadyTaken(_) => EmailAddressAlreadyTaken(Some(e)) case OtherIdentityError(m, d, _endpoint) => OtherIdentityError(m, d, endpoint = Some(e)) } } @@ -46,6 +48,9 @@ object IdentityErrorResponse { /** The email address is invalid. */ case class InvalidEmailAddress(endpoint: Option[IdentityEndpoint]) extends IdentityError + /** The email address is already associated with an existing account. */ + case class EmailAddressAlreadyTaken(endpoint: Option[IdentityEndpoint]) extends IdentityError + /** Some other error occurred. */ case class OtherIdentityError(message: String, description: String, endpoint: Option[IdentityEndpoint]) extends IdentityError @@ -65,6 +70,8 @@ object IdentityErrorResponse { EmailProviderRejected(endpoint = None) } else if (message == "Invalid emailAddress:" && description == "Please enter a valid email address") { InvalidEmailAddress(endpoint = None) + } else if (message == "Email in use" && description == "This email has already been taken") { + EmailAddressAlreadyTaken(endpoint = None) } else { OtherIdentityError(message, description, endpoint = None) }