First, let me state that all of the following code works except forgetting the error to display on the page and that is a big problem! With that said, I have googled all day and have read at least 25 different posts about having the same problem and have tried several different things in several different places. Please see the bottom of this question for things I have already tried. Here's the code:
********This Code Has Been Edited With The Changes Suggested Through 9/21/2017********
Visualforce page:
<apex:page standardController="Case" extensions="CaseControllerExt" Title="New Warranty Claim" showHeader="false" id="createNewWarranty" docType="html-5.0">
<script type='text/javascript' src='/canvas/sdk/js/publisher.js'/>
<script>
function refreshFeed(){
Sfdc.canvas.publisher.publish({name : 'publisher.refresh', payload : {feed:true}});
}
</script>
<apex:stylesheet value="{!$Resource.NewWarrantyClaimButtonVFPageCSS}"/>
<apex:form >
<apex:pageBlock title="New Warranty Claim" id="viewCreateClaim">
<apex:outputPanel id="pageMessages">
<apex:outputText value="This is where error messages should get shown!"></apex:outputText>
<apex:pageMessages id="showErrors" showDetail="true"/>
</apex:outputPanel>
<apex:outputPanel styleClass="explanation" rendered="{!showCreateButtons}">
<p>
<apex:outputText value="These buttons will create a new Warranty Claim if the product has been registered and marked as a faulty unit on the Case."></apex:outputText>
</p>
<p>
<apex:outputText value="If none of the products that are marked faulty have been registered you will be instructed to create the Warranty Claim manually."></apex:outputText>
</p>
</apex:outputPanel>
<apex:pageBlockButtons id="createButtons" styleclass="displayBlock" rendered="{!showCreateButtons}">
<apex:actionFunction action="{!unitReplacement}" name="unitReplacement"/>
<button type="button" value="unitReplacement" onclick="unitReplacement();">Create Warranty Claim For Unit Replacement</button>
<apex:actionFunction action="{!partsUnderWarranty}" name="partsUnderWarranty"/>
<button type="button" value="partsUnderWarranty" onclick="partsUnderWarranty();">Create Warranty Claim For Parts - Unit Under Warranty</button>
<apex:actionFunction action="{!partsOutOfWarranty}" name="partsOutOfWarranty"/>
<button type="button" value="partsOutOfWarranty" onclick="partsOutOfWarranty();">Create Warranty Claim For Parts - Unit Out of Warranty (90 days for parts and 1 year compressor)</button>
</apex:pageBlockButtons>
</apex:pageBlock>
<apex:pageBlock id="viewClaim" >
<apex:outputPanel rendered="{!showViewButtons}">
<apex:outputPanel >
<p>
<apex:outputText value="To view the claim that was created and finish adding the required information, click the button labled View Warranty Claim."></apex:outputText>
</p>
</apex:outputPanel>
</apex:outputPanel>
<apex:pageBlockButtons rendered="{!showViewButtons}">
<apex:actionFunction action="{!createWarranty}" name="createWarranty" rerender="pageMessages" oncomplete="refreshFeed();"/>
<button type="button" value="createWarranty" onclick="createWarranty();">View Warranty Claim</button>
</apex:pageBlockButtons>
</apex:pageBlock>
</apex:form>
Controller:
public with sharing class CaseControllerExt {
private final SObject parent;
public String firstError {get;set;}
public String secondError {get;set;}
public String thirdError {get;set;}
public String fourthError {get;set;}
public String fifthError {get;set;}
public String lastError {get;set;}
public String unitReplacement {get;set;}
public String partsUnderWarranty {get;set;}
public String partsOutOfWarranty {get;set;}
public String recordTypeToSwitchTo {get;set;}
public Id Id {get;set;}
public Id warrantyClaimId {get;set;}
public Id recordTypeId {get;set;}
public List<Id> warrantyClaimIds {get;set;}
public List<Id> caseIdsAndRecordTypeId = new List<Id>();
public boolean showCreateButtons {get;set;}
public boolean showViewButtons {get;set;}
public Case cs;
public HVAC_Warranty_Claim_Form__c cf;
private ApexPages.StandardController sc;
// List<ApexPages.Message> errorList = new List<ApexPages.Messages>();
public CaseControllerExt(ApexPages.StandardController controller){
try{
showViewButtons = false;
System.debug('$$$$$showViewButtons - ControllerExtension$$$$$' + showViewButtons);
showCreateButtons = true;
System.debug('$$$$$showCreateButtons - ControllerExtension$$$$$' + showCreateButtons);
parent = controller.getRecord();
System.debug('*****Parent Record*****' + parent);
cs = new Case();
cs.AccountId = parent.id;
System.debug('*****Case Record Id aka cs.AccountId*****' + cs.AccountId);
System.debug('*****Case Record*****' + cs);
caseIdsAndRecordTypeId.add(cs.AccountId);
System.debug('*****caseIdsAndRecordTypeId List*****' + caseIdsAndRecordTypeId);
// lastError = '';
System.debug('*****Case Record Id aka cs.AccountId*****' + cs.AccountId);
System.debug('*****Case Record*****' + cs);
// System.debug('*****lastError*****' + lastError);
}catch (Exception ex1){
ApexPages.addMessages(ex1);
firstError = ex1.getMessage();
System.debug('@@@@@firstError@@@@@' + firstError);
}
}
public void unitReplacement(){
try{
showViewButtons = true;
System.debug('$$$$$showViewButtons - UnitReplacement$$$$$' + showViewButtons);
showCreateButtons = false;
System.debug('$$$$$showCreateButtons - UnitReplacement$$$$$' + showCreateButtons);
unitReplacement = 'Unit Replacement';
System.debug('^%^%^%^%^unitReplcmnt^%^%^%^%^' + unitReplacement);
recordTypeToSwitchTo = unitReplacement;
System.debug('^%^%^%^%^recordTypeToSwitchTo^%^%^%^%^' + recordTypeToSwitchTo);
assignRecordType(recordTypeToSwitchTo);
}catch (Exception ex2){
ApexPages.addMessages(ex2);
secondError = ex2.getMessage();
System.debug('@@@@@secondError@@@@@' + secondError);
}
}
public void partsUnderWarranty(){
try{
showViewButtons = true;
System.debug('$$$$$showViewButtons - UnderWarranty$$$$$' + showViewButtons);
showCreateButtons = false;
System.debug('$$$$$showCreateButtons - UnderWarranty$$$$$' + showCreateButtons);
partsUnderWarranty = 'Parts - Unit Under Warranty';
System.debug('^%^%^%^%^partsUnderWarranty^%^%^%^%^' + partsUnderWarranty);
recordTypeToSwitchTo = partsUnderWarranty;
System.debug('^%^%^%^%^recordTypeToSwitchTo^%^%^%^%^' + recordTypeToSwitchTo);
assignRecordType(recordTypeToSwitchTo);
}catch (Exception ex3){
ApexPages.addMessages(ex3);
thirdError = ex3.getMessage();
System.debug('@@@@@thirdError@@@@@' + thirdError);
}
}
public void partsOutOfWarranty(){
try{
showViewButtons = true;
System.debug('$$$$$showViewButtons - OutOfWarranty$$$$$' + showViewButtons);
showCreateButtons = false;
System.debug('$$$$$showCreateButtons - OutOfWarranty$$$$$' + showCreateButtons);
partsOutOfWarranty = 'Parts - Unit Out of Warranty (90 days for parts and 1 year compressor)';
System.debug('^%^%^%^%^partsOutOfWarranty^%^%^%^%^' + partsOutOfWarranty);
recordTypeToSwitchTo = partsOutOfWarranty;
System.debug('^%^%^%^%^recordTypeToSwitchTo^%^%^%^%^' + recordTypeToSwitchTo);
assignRecordType(recordTypeToSwitchTo);
}catch (Exception ex4){
ApexPages.addMessages(ex4);
fourthError = ex4.getMessage();
System.debug('@@@@@fourthError@@@@@' + fourthError);
}
}
public PageReference createWarranty(){
warrantyClaimId = createNewWarranty(warrantyClaimId);
PageReference claimView = new PageReference('/' + warrantyClaimId);
System.debug('!!!!!!Page To Redirect To!!!!!' + claimView);
claimView.setRedirect(true);
return claimView;
}
public void assignRecordType(String recordTypeToSwitchTo){
try{
recordTypeId = Schema.SObjectType.HVAC_Warranty_Claim_Form__c.getRecordTypeInfosByName().get(recordTypeToSwitchTo).getRecordTypeId();
System.debug('^%^%^%^%^recordTypeId^%^%^%^%^' + recordTypeId);
caseIdsAndRecordTypeId.add(recordTypeId);
System.debug('^%^%^%^%^caseIdsAndRecordTypeId^%^%^%^%^' + caseIdsAndRecordTypeId);
}catch (Exception ex5){
ApexPages.addMessages(ex5);
fifthError = ex5.getMessage();
System.debug('@@@@@fifthError@@@@@' + fifthError);
}
}
private Id createNewWarranty(Id warrantyClaimId){
if(caseIdsAndRecordTypeId.size() != 2){
ApexPages.Message noFaultyProduct = new ApexPages.message(ApexPages.Severity.FATAL, 'There was an error getting the Case Id! Please close this window, refresh the window your Case is open in and try again. Should you receive this meassage again, please contact your Mitsubishi Electric Representative.');
ApexPages.addMessage(noFaultyProduct);
return null;
}
warrantyClaimIds = FindIfEnteredFromSAP.wasProductInfoRecordCreatedFromScan(caseIdsAndRecordTypeId);
if (warrantyClaimIds[0] == null){
ApexPages.Message noFaultyProduct = new ApexPages.message(ApexPages.Severity.FATAL, 'You have not marked any case products as faulty units! Please close this window and make the necessary change(s).');
ApexPages.addMessage(noFaultyProduct);
return null;
}else{
warrantyClaimId = warrantyClaimIds[0];
}
try{
FeedItem post = new FeedItem();
post.parentId = ApexPages.currentPage().getParameters().get('id');
post.Body = 'A new Warranty Claim has been created';
post.Type = 'LinkPost';
post.LinkUrl = '/' + warrantyClaimId;
post.Title = 'The new claim can be found here!';
insert post;
System.debug('!!!!!!Chatter Post created!!!!!' + post.LinkUrl);
} catch(System.Exception ex6){
lastError = ex6.getMessage();
System.debug('!!!!!!Chatter Post NOT created!!!!!' + lastError);
}
return warrantyClaimId;
}}
Apex Class:
public class FindIfEnteredFromSAP {
// @InvocableMethod(label='Create New Warranty Claim' description='Creates a new Warranty Claim based on information from the Product Information Record')
public static List<String> wasProductInfoRecordCreatedFromScan(List<Id> caseIdsAndRecordTypeId){
System.debug('!!!!!caseIdsAndRecordTypeId!!!!!' + caseIdsAndRecordTypeId);
Id caseId = caseIdsAndRecordTypeId[0];
System.debug('!!!!!caseId!!!!!' + caseId);
Id recordTypeIdToChangeTo = caseIdsAndRecordTypeId[1];
// Get list of Case Products that are marked faulty on the case
List<Case_Product__c> faultyProducts = new List<Case_Product__c>();
faultyProducts = [SELECT Id FROM Case_Product__c WHERE Case__c =:caseId AND Faulty_Unit__c = True];
System.debug('!*!*!*!*!*!faultyProducts!*!*!*!*!*!' + faultyProducts);
// Find out how long the list of faulty products is
Integer sizeOfFaultyProduct = faultyProducts.size();
System.debug('!*!*!*!*!*!faultyProducts.size!*!*!*!*!*!' + faultyProducts.size());
if (sizeOfFaultyProduct == 0){
ApexPages.Message noFaultyProduct = new ApexPages.message(ApexPages.Severity.FATAL, 'You have not marked any case products as faulty units! Please close this window and make the necessary change(s).');
ApexPages.addMessage(noFaultyProduct);
return null;
}
// Subtract one since size of lists is not zero based (i will be reused when creating some new counters)
Integer i = sizeOfFaultyProduct - 1;
System.debug('!*!*!*!*!*!SizeOf i !*!*!*!*!*!' + i);
Integer j;
Integer k;
Integer l = 0;
Integer m;
List<Id> faultyProductId = new List<Id>();
try{
// Get each of the faulty case product Id's because until this apex knows them as Case_Product__c objects
for (j = i; j > -1; j--){
faultyProductId.add(faultyProducts[j].id);
System.debug('!*!*!*!*!*!faultyProductId!*!*!*!*!*!' + faultyProductId);
}
}catch(System.Exception e){
ApexPages.Message noFaultyProduct = new ApexPages.message(ApexPages.Severity.FATAL, 'You have not marked any case products as faulty units! Please close this window and make the necessary change(s).');
ApexPages.addMessage(noFaultyProduct);
return null;
}
// Iterate through each faulty product until you find one with a Warranty_Number__c
// which indicates it was actually registered by a person, not a scan only.
List<Case_Product__c> productInfoList = new List<Case_Product__c>();
List<Warranty__c> productToTest = new List<Warranty__c>();
List<String> warrantyNumber = new List<String>();
List<Id> productInfoId = new List<Id>();
Integer sizeOfProductToTest;
Integer sizeOfProductInfoId;
Integer sizeOfProductInfoList;
Integer n;
for (k = i; k > -1; k--){
System.debug('!*!*!*!*!*!k!*!*!*!*!*!' + k);
// Get a list of Product_Registration__c's from each Case_Product that is marked faulty
productInfoList.add([SELECT Product_Registration__c FROM Case_Product__c WHERE Id = :faultyProductId[k]]);
sizeOfProductInfoList = productInfoList.size();
System.debug('!*!*!*!*!*!productInfoList.size!*!*!*!*!*!' + productInfoList.size());
System.debug('!*!*!*!*!*!productInfoList!*!*!*!*!*!' + productInfoList);
}
// Put the Id's from the Product_Registration's into a list
for (Case_Product__c cp : productInfoList)
{
productInfoId.add(cp.Product_Registration__c);
System.debug('!*!*!*!*!*!productInfoId!*!*!*!*!*!' + productInfoId);
}
n = sizeOfProductInfoList - 1;
System.debug('#####sizeOfProductInfoList#####' + sizeOfProductInfoList);
System.debug('#####n#####' + n);
for (m = n; m > -1; m--){
// Get the Warranty_Number's from each faulty product Id
productToTest.add([SELECT warranty_number__c FROM Warranty__c WHERE Id =:productInfoID[m]]);
System.debug('!*!*!*!*!*!productToTest!*!*!*!*!*!' + productToTest);
}
// put those warranty numbers into a string list since apex considers them to be warranty__c objects currently
for (Warranty__c ptt : productToTest)
{
warrantyNumber.add(ptt.warranty_number__c);
System.debug('!*!*!*!*!*!warrantyNumber!*!*!*!*!*!' + warrantyNumber);
}
sizeOfProductToTest = warrantyNumber.size();
System.debug('!*!*!*!*!*!warrantyNumber.size!*!*!*!*!*!' + warrantyNumber.size());
sizeOfProductInfoId = productInfoId.size();
System.debug('!*!*!*!*!*!productInfoId.size!*!*!*!*!*!' + productInfoId.size());
List<Id> warrantyClaimIds = new List<Id>();
List<Id> productInfoIds = new List<Id>();
for (Case_Product__c cp : productInfoList)
{
productInfoIds.add(cp.Product_Registration__c);
System.debug('!*!*!*!*!*!productInfoIds!*!*!*!*!*!' + productInfoIds);
}
List<String> registeredProducts = new List<String>();
// Find out if the warrantyNumber list is empty and if the number . If it isn't,
If (sizeOfProductToTest != 0 && sizeOfProductToTest == sizeOfProductInfoId){
for (l = 0; l <= i; l++){
if (warrantyNumber[l] != null){
registeredProducts.add(String.valueOf(productInfoId[l]));
System.debug('!*!*!*!*!*!productInfoList!*!*!*!*!*!' + registeredProducts);
warrantyClaimIds = getRegistrationInfoFromProductInfo.getRegistrationInfo(registeredProducts, productInfoIds, caseId, recordTypeIdToChangeTo);
break;
}
}
}
return warrantyClaimIds;
}}
Here is the end of the second debug log from clicking the button on the VF page (Code no longer calls my apex class):
14:20:17.0 (21496393)|USER_DEBUG|[121]|DEBUG|^%^%^%^%^caseIdsAndRecordTypeId^%^%^%^%^(500e000000AwKVoAAN, 01231000000y0SAAAY)
14:20:17.0 (21506080)|SYSTEM_METHOD_EXIT|[121]|System.debug(ANY)
14:20:17.0 (21519425)|METHOD_EXIT|[82]|01pe0000000F7Px|CaseControllerExt.assignRecordType(String)
14:20:17.0 (21525737)|SYSTEM_MODE_EXIT|false
14:20:17.0 (21553866)|VF_APEX_CALL_END|CaseControllerExt invoke(partsUnderWarranty)
14:20:17.24 (24626500)|VF_APEX_CALL_START|[EXTERNAL]|/apexpage/pagemessagescomponentcontroller.apex set(conEscape,null)
14:20:17.24 (24646758)|SYSTEM_MODE_ENTER|true
14:20:17.24 (24657778)|VF_APEX_CALL_START|[EXTERNAL]|PageMessagesComponentController set(conEscape,null)
14:20:17.24 (24679474)|VF_APEX_CALL_START|[EXTERNAL]|PageMessagesComponentController invoke(setconEscape)
14:20:17.24 (24709905)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
14:20:17.24 (24717301)|VARIABLE_SCOPE_BEGIN|[88]|this|ApexPage.PageMessagesComponentController|true|false
14:20:17.24 (24740904)|VARIABLE_ASSIGNMENT|[88]|this|{}|0x7a6c3d5a
14:20:17.24 (24749221)|VARIABLE_SCOPE_BEGIN|[88]|escape|Boolean|false|false
14:20:17.24 (24757068)|VARIABLE_ASSIGNMENT|[88]|escape|null
14:20:17.24 (24853508)|VF_APEX_CALL_START|[EXTERNAL]|/apexpage/pagemessagescomponentcontroller.apex get(severities)
14:20:17.24 (24869071)|SYSTEM_MODE_ENTER|true
14:20:17.24 (24880351)|VF_APEX_CALL_START|[EXTERNAL]|PageMessagesComponentController invoke(getseverities)
14:20:17.24 (24896439)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
14:20:17.24 (24902104)|VARIABLE_SCOPE_BEGIN|[2]|this|ApexPage.PageMessagesComponentController|true|false
14:20:17.24 (24919846)|VARIABLE_ASSIGNMENT|[2]|this|{}|0x7a6c3d5a
14:20:17.0 (25250803)|VF_APEX_CALL_START|[EXTERNAL]|01pe0000000F7Px|CaseControllerExt get(showCreateButtons)
14:20:17.0 (25262913)|SYSTEM_MODE_ENTER|true
14:20:17.0 (25270248)|VF_APEX_CALL_START|[EXTERNAL]|01pe0000000F7Px|showCreateButtons
14:20:17.0 (25281553)|VF_APEX_CALL_END|showCreateButtons
14:20:17.0 (25294642)|VF_APEX_CALL_END|CaseControllerExt get(showCreateButtons)
14:20:17.0 (25362881)|VF_APEX_CALL_START|[EXTERNAL]|01pe0000000F7Px|CaseControllerExt get(showViewButtons)
14:20:17.0 (25371440)|SYSTEM_MODE_ENTER|true
14:20:17.0 (25377438)|VF_APEX_CALL_START|[EXTERNAL]|01pe0000000F7Px|showViewButtons
14:20:17.0 (25385956)|VF_APEX_CALL_END|showViewButtons
14:20:17.0 (25396748)|VF_APEX_CALL_END|CaseControllerExt get(showViewButtons)
14:20:17.27 (27544259)|VF_APEX_CALL_START|[EXTERNAL]|/apexpage/pagemessagescomponentcontroller.apex set(conEscape,null)
14:20:17.27 (27560831)|SYSTEM_MODE_ENTER|true
14:20:17.27 (27575324)|VF_APEX_CALL_START|[EXTERNAL]|PageMessagesComponentController set(conEscape,null)
14:20:17.27 (27593095)|VF_APEX_CALL_START|[EXTERNAL]|PageMessagesComponentController invoke(setconEscape)
14:20:17.27 (27611632)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
14:20:17.27 (27618698)|VARIABLE_SCOPE_BEGIN|[88]|this|ApexPage.PageMessagesComponentController|true|false
14:20:17.27 (27640289)|VARIABLE_ASSIGNMENT|[88]|this|{}|0x7a6c3d5a
14:20:17.27 (27651257)|VARIABLE_SCOPE_BEGIN|[88]|escape|Boolean|false|false
14:20:17.27 (27658760)|VARIABLE_ASSIGNMENT|[88]|escape|null
14:20:17.27 (27762807)|VF_APEX_CALL_START|[EXTERNAL]|/apexpage/pagemessagescomponentcontroller.apex get(severities)
14:20:17.27 (27775727)|SYSTEM_MODE_ENTER|true
14:20:17.27 (27788356)|VF_APEX_CALL_START|[EXTERNAL]|PageMessagesComponentController invoke(getseverities)
14:20:17.27 (27807326)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
14:20:17.27 (27812480)|VARIABLE_SCOPE_BEGIN|[2]|this|ApexPage.PageMessagesComponentController|true|false
I have tried the following:
- I have put the error handling in both a if statement as well as a try/catch.
- I have used
<apex:pageMessages/>
as well as<apex:pageMessages></apex:pageMessages>
- I have put the
apex:pageMessages
as a direct child of the form as well as the page block. - I have put the
- I have tried to rerender them from the three buttons (unitReplacement, partsUnderWarranty, and partsOutOfWarranty) where the error would be called from.
- I have tried to rerender the outputpanel that I wrapped them in.
6. When I do either #5 or #6 the my apex class does not get called, which I think is the problem, but I don't know how to fix it. - My fourth button in the second page block is not part of this problem, but I would like to know if rerender="out" is what's making the page a pop-out because I can't find any documentation that indicates that's a possible value.
Best Answer
First problem: this
return
statement is outside of theif
scope braces and this code will always return null. Based on your other code, you intended the return to be inside the braces.Second problem: the reason you are not seeing the page messages is because your code is throwing an exception which you're not handling and that behavior trumps all others. It is occurring here:
warrantyClaimIds
isnull
in this context andwarrantyClaimIds[0]
is trying to get index value 0 from null and an exception is thrown.Determining what's happening looks daunting but you can see the system popping items from the call stack as it unwinds itself from the place where the exception is being thrown.
This ^^ is the exit from the getter property within
warrantyClaimIds
which you reference on line 94 of your page controller classThis ^^ is the exit from the
createNewWarranty
methodSo, an exception was thrown immediately after executing the getter on line 94, and that exception went unhandled. Even though (as you demonstrated) the page messages collection has your error stuff in it - you'll never see it when an exception is thrown and the exception isn't handled correctly.
You should check for
null
before calling[0]
here:warrantyClaimId = warrantyClaimIds[0];
or you could wrap this code in the try/catch or implement something else in your code ensure you don't ever get a null value for this List.From the discussion in comments:
The absolute, most generic, exception handling you could implement in the page controller. Wrap each method in a try/catch and in the catch block, output the exception details to the pagemessages collection to be shown onscreen. It's not pretty, but the code will execute in most cases and if there's a problem it'll be shown to the user.