InstantiateTemplateResponse can return an empty email
In CreateCustomEmail.cs, the InstantiateTemplateResponse can return an empty email if the template is not set up correctly.
I think there needs to be a check on the email.Id to make sure it is not equivalent to Guid.Empty.
I'm just looking at the code by eye, but it looks like getting Guid.Empty is expected here. I'm assuming you mean the InstantiateTemplateResponse in the GetEmailInstantiateFromTemplate method. If you follow that email entity record through the process, in the CreateEmail method you see:
TraceService.Trace("Email is going to be created");
email.Id = this.OrganizationService.Create(email);
TraceService.Trace("Email has been created correctly. ID:{0}",email.Id);
The InstantiateTemplateRequest doesn't store the email into the database, it only creates an email in memory and returns the object. All the other text processing and token-replacement in the project happens before the email is created in the system (and that's when it gets an Id).
And yes, you could get an empty email body if the template is incorrect, but checking for Guid.Empty won't help you, as it will always be Guid.Empty at that point.
If the template is incorrect, then there shouldn't be a point going any further.
In GetEmailInstantiateFromTemplate, it will always log
TraceService.Trace("Email Template has been instanciated correctly. Email ID:{0}", email.Id); whether or not a template was found or not.
If it can find a template, a valid Guid is stored in email.Id, otherwise it is Guid.Empty. (It's been 4 months, but I am pretty sure this is correct)
I believe that if email.Id is Guid.Empty, then the email has not been instantiated correctly and it should be handled properly (via logging or exception) in GetEmailInstantiateFromTemplate or later on the creation of the email.
Again, it's been 4 months since I reported this, but I think I had the incorrect name, and this would have helped troubleshoot my issue a lot easier.
That makes some sense, but the InstantiateTemplateRequest takes an ID for the Template, not a name. If the name of the template was not found, that would appear in the RetrieveEmailTemplate method -- and in that case, an exception is thrown with a pretty meaningful message.
if (templatesCollection.Entities.Count == 0)
throw new Exception("A template couldn't be found with name " + templateName);
else if (templatesCollection.Entities.Count > 1)
throw new Exception("There is more than one template with name " + templateName);
else
{
TraceService.Trace("Email Template has been retrieved correctly");
return templatesCollection.Entities[0];
}
I haven't run this recently either, but my understanding is that Guid.Empty is the normal value for the returned email entity, because it doesn't create the record in the system. Guid.Empty in this case isn't an error indicator, it's always the ID of any record that doesn't exist.
I know that because I just had to fix a bunch of javascript in a 2011-2016 migration because it used getId() ==null to detect when it was on the create form instead of using getFormType() == 0.
What you said makes sense. I'll investigate further later with an incorrect template name again and see what I get in the logs...