Membership application confirmation page after anonymization
Closed, ResolvedPublic5 Story Points


Membership application records with empty ('') email address - presumably after anonymization - cause unhandled exception.


  • a page is being displayed that confirms the process and points out that the given data can't be displayed anymore
  • The message is Ihr Mitgliedschaftsantrag wurde erfolgreich abgeschlossen, die Bestätigungsseite kann allerdings nicht mehr angezeigt werden. Fragen zu Ihrer Mitgliedschaft können Sie uns gern per E-Mail an stellen.
  • The e-mail address in the message is a mailto link


These cases can be determined by looking at the backup timestamp in the database record. This might not be part of the domain model, though.

GET /show-membership-confirmation?id=xxx&accessToken=xxx
[2017-12-18 07:41:56] index_php.ERROR: Given email address could not be parsed {"code":0,"file":"/usr/share/nginx/www/","line":21,"stack_trace":"#0 /usr/share/nginx/www/ WMDE\\EmailAddress\\EmailAddress->__construct('')\n#1 /usr/share/nginx/www/ WMDE\\Fundraising\\Frontend\\MembershipContext\\DataAccess\\DoctrineApplicationRepository->newApplicationDomainEntity(Object(WMDE\\Fundraising\\Entities\\MembershipApplication))\n#2 /usr/share/nginx/www/ WMDE\\Fundraising\\Frontend\\MembershipContext\\DataAccess\\DoctrineApplicationRepository->getApplicationById(27035)\n#3 /usr/share/nginx/www/ WMDE\\Fundraising\\Frontend\\MembershipContext\\Infrastructure\\LoggingApplicationRepository->getApplicationById(27035)\n#4 /usr/share/nginx/www/ WMDE\\Fundraising\\Frontend\\MembershipContext\\UseCases\\ShowMembershipApplicationConfirmation\\ShowMembershipApplicationConfirmationUseCase->getMembershipApplicationById(27035)\n#5 /usr/share/nginx/www/ WMDE\\Fundraising\\Frontend\\MembershipContext\\UseCases\\ShowMembershipApplicationConfirmation\\ShowMembershipApplicationConfirmationUseCase->showConfirmation(Object(WMDE\\Fundraising\\Frontend\\MembershipContext\\UseCases\\ShowMembershipApplicationConfirmation\\ShowMembershipAppConfirmationRequest))\n#6 [internal function]: {closure}(Object(Symfony\\Component\\HttpFoundation\\Request))\n#7 /usr/share/nginx/www/ call_user_func_array(Object(Closure), Array)\n#8 /usr/share/nginx/www/ Symfony\\Component\\HttpKernel\\HttpKernel->handleRaw(Object(Symfony\\Component\\HttpFoundation\\Request), 1)\n#9 /usr/share/nginx/www/ Symfony\\Component\\HttpKernel\\HttpKernel->handle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#10 /usr/share/nginx/www/ Silex\\Application->handle(Object(Symfony\\Component\\HttpFoundation\\Request))\n#11 /usr/share/nginx/www/ Silex\\Application->run()\n#12 {main}"} []
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptDec 19 2017, 8:25 AM
kai.nissen updated the task description. (Show Details)Dec 21 2017, 2:04 PM
Pablo-WMDE set the point value for this task to 5.Dec 21 2017, 2:07 PM

PR introduces the assumption that for purged donations the donor will be null. If you introduce a new class like PurgedDonor, please adjust the code in DonationMembershipApplicationAdapter::getInitialValidationState accordingly.

JeroenDeDauw moved this task from Ready to Doing on the WMDE-Fundraising-Funban-2 board.
JeroenDeDauw added a comment.EditedDec 22 2017, 3:18 PM

DB fields that get purged for memberships:

		'anrede' => '',
		'firma' => '',
		'titel' => '',
		'name' => '',
		'vorname' => '',
		'nachname' => '',
		'strasse' => '',
		'plz' => '',
		'ort' => '',
		'email' => '',
		'phone' => '',
		'dob' => null,
		'account_number' => '',
		'bank_name' => '',
		'bank_code' => '',
		'account_holder' => ''

Corresponds to:

  • MembershipContext\Domain\Model\Applicant except countryCode
  • Part of PaymentMethod
    • Part of PayPalPayment
    • All of DirectDebitPayment

@gabriel-wmde I'm not sure how to make the Null Object pattern work here. We'd need a null object for both Applicant and PaymentMethod. These Value Objects do not follow Tell Don't Ask at all, which is something I think you kinda need to make the Null Object Pattern work. If we simply create such an object with empty values we'll still going to need special handling for most access happening to the data, which is not good. Perhaps you thought of something I did not...

Talked to Kai and this is the plan for now: have the Doctrine repo throw an (ApplicationPurged) exception when the data was purged. This forces the 4 UCs retrieving an Application to add a try catch which will fix their current error out in case of purged data. It is not entirely clear if this solution will remain viable as we add more UCs, but since it is low effort to implement we decided to try it out for now and adjust if it turns out to not work well later.

@JeroenDeDauw wrote

Still, before the (purged) task is done, these TODOs in the presenter should be taken care off.

What is still missing is the UI for the "your info was anonimized but everything is OK" and "a technical error occurred" cases. For both of these it would be nice to have some kind of specification for that the page should look like. Is it fine to use a simple template that just takes a message and looks like the "access denied" one for both, or do things such as the links on the "success case" page also need to be shown?

@kai.nissen will be ooo for quite some time now, so I guess it makes sense to go for the message implementation and see if that is good enough.

I had a look at the PR and would like to give a summary of the current state behavior:

  • The "Happy path" (display membership application) works like before.
  • When an error occurs (membership application ID not found) or when the membership application is purged, a plain text message without the page layout is displayed.

From a UX perspective, this is only marginally better than the blank page we get on error messages, IMHO. Although the AC say "page" without specifying its design, I think we should go forward and use templates in the MembershipApplicationConfirmationHtmlPresenter. We could (re)use the System_Message.html.twig template for that.

@JeroenDeDauw Will you be able to do it or should one of the other team members pick up this task?

I am not planning to do this

kai.nissen updated the task description. (Show Details)Feb 2 2018, 12:41 PM

In case the membership application has already been anonymized, the page should look like the "Access denied" page. I updated the task description accordingly.

When passing an invalid data set ID, the "Access Denied" page is being displayed, because either the token is not given or it is invalid. I think, that's fine.

Pablo-WMDE removed Pablo-WMDE as the assignee of this task.
Pablo-WMDE claimed this task.
Pablo-WMDE added a comment.EditedFeb 7 2018, 10:16 AM

Comment contradicting ("the page should look like") description. Restarting.

Pablo-WMDE removed Pablo-WMDE as the assignee of this task.
Pablo-WMDE claimed this task.
Pablo-WMDE removed Pablo-WMDE as the assignee of this task.

The heading of the page that displays the "we can no longer show your confirmation" text (for the anonymization case) says "Error". Don't know if that is a good heading, @kai.nissen ? But apart from that, everything works.

gabriel-wmde removed gabriel-wmde as the assignee of this task.

Deployed to test and prod.

kai.nissen closed this task as Resolved.Feb 16 2018, 11:07 AM
kai.nissen claimed this task.