[SalesForce] Help with error: List has no rows for assignment to SObject

I have created a Visualforce page, which has a commandbutton on it. The code for this is:

<apex:page standardController="Disease__c" extensions="myExtension" title="Button">
<apex:commandButton value="Notify" styleClass="options" action="{!notifyPatients}"/>
</apex:page>

So, in my Visualforce page I call a method "notifyPatients" in my extension "myExtension".

The extension class looks like this:

public with sharing class myExtension {

    public Disease__c d {get; set;}

    public myExtension(ApexPages.StandardController controller){
        d = (Disease__c) controller.getRecord();
        }
    }

    public void notify() {
        emailHandler.sendNotification(d);
    }
}

And above I then call a method in my emailHandler class to send out a notification.
This looks like the code below:

public with sharing class emailHandler {
  public static void sendNotification(Disease__c d) {
  EmailTemplate template = [SELECT Id, Subject, HtmlValue, Body FROM EmailTemplate WHERE Name = 'NotifyPatients']; 
  [...]

  }
}

And now, when I click on my button in the visualforce page, I get the following error message, which is displayed in the Salesforce user interface:

List has no rows for assignment to SObject
Error is in expression '{!notifyPatients}' in component <apex:commandButton> in page buttonsPage

An unexpected error has occurred. Your development organization has been notified.

Thanks in advance.

Best Answer

The List has no rows for assignment to SObject error is referring to a SOQL statement that is trying to store the result as a single SObject but no rows are being returned.

The code below will cause that error because there is no EmailTemplate records being returned:

EmailTemplate template = [SELECT Id, Subject, HtmlValue, Body 
                              FROM EmailTemplate WHERE Name = 'NotifyPatients']; 

Based on your comments on the question the above SOQL should of been using DeveloperName rather than Name in the where condition as shown below.

EmailTemplate template = [SELECT Id, Subject, HtmlValue, Body 
                             FROM EmailTemplate WHERE DeveloperName = 'NotifyPatients'];

A more robust solution that handles these scenarios in a more user friendly manner is shown below

List<EmailTemplate> templates = [SELECT Id, Subject, HtmlValue, Body 
                             FROM EmailTemplate WHERE DeveloperName = 'NotifyPatients'];
if (templates.size() > 0) {
    // Do something 
} else {
    ApexPages.addMessage(new ApexPages.Message(
        ApexPages.Severity.Error,'No EmailTemplates found.')
        );
}
Related Topic