Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

i am having an issue where my code does not stop executing even after an exception has thrown. In the following code, i want to display an error message on the page when the user did not enter an Account Number on the account record. When i checked in debug log it shows the exception message when i left the Account Number as blank. But on the page, it is not showing error. I already have apex:pagemessages in my visualforce page. Also, the code is continue to execute the getCustCreditInfo method even after the exception thrown. Why this is happening?

    public with sharing class CustomerCreditInfoController {
    private final Account acct;
    public CustomerCreditInfo cci; 
    public String CustNo {get;set;}
    private List<String> lstReqData {get;set;}

    public static final String  SFDC_ERROR_TYPE = 'SFDC';
    public static final String  SFDC_ERROR = 'SFDC0001';
    public static final String  GENERIC_ERROR = 'GEN0001';
    public static final String  GENERIC_ERROR_TYPE = 'Generic';


    public CustomerCreditInfoController(ApexPages.StandardController stdController) {
        if(!Test.isRunningTest()) {
            List<String> addl = new List<String> {};
            addl.add('accountnumber');
            stdController.addFields(addl);
        }
        this.acct = (Account)stdController.getRecord();
        System.debug('acct:'+acct);
        try {
            if(acct.AccountNumber == null || acct.AccountNumber == '') {
                System.debug('Accontnumber is null');
                throw new CustomException(Utility.getException(SFDC_ERROR,SFDC_ERROR_TYPE));
            } else {
                CustNo = acct.AccountNumber;    
            }
        } catch(Exception e) {
            ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR,e.getMessage()); 
            ApexPages.addMessage(myMsg);
            System.debug('inside catch block');
        }
    }

    public CustomerCreditInfo getCustCreditInfo() {
        try {
            DMsapComDocumentSapSoapFunctionsMcS.Z_GSSMWFM_HNDL_EVNTRQST00_Binding sap1 = new DMsapComDocumentSapSoapFunctionsMcS.Z_GSSMWFM_HNDL_EVNTRQST00_Binding();       
            Map<String,String> mapSAP = new Map<String,String> {};
            DMsapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01 req = new DMsapComDocumentSapSoapFunctionsMcS.ZgssmbstDatarcrd01();      
            lstReqData = new List<String> {};
            //populating item values

            String EventType = 'EVENT[.]SFDC-CUSTOMER-CREDIT-INFO-GET[.]VERSION[.]0[.]RESPONSE-TYPE[.]FULL-SETS';
            String InputFields = '';
            String InputData = 'ZGSEST_CSTMRSRCH01[.]'+CustNo;
            lstReqData.add(EventType);
            lstReqData.add(InputFields);
            lstReqData.add(InputData);
            req.item = Utility.LoadRequestData(lstReqData);
            sap1.timeout_x = 90000;
            ProcessorControl.inGetCreditInfo = true;
            DMsapComDocumentSapSoapFunctionsMcS.ZGssmwfmHndlEvntrqst00Response_element ret =  sap1.ZGssmwfmHndlEvntrqst00('',req);
            mapSAP = Utility.ParseResponse(ret);

            cci = new CustomerCreditInfo(); 
            if(!mapSAP.isEmpty() && mapSAP.size()>0) {
                    cci.CreditBlock = mapSAP.get('CRBLB');
                    cci.RiskCategory = mapSAP.get('CTLPC');
                    cci.RiskClass = mapSAP.get('CTLPC_TEXT');
                    cci.Rating = mapSAP.get('DBRTG');
                    cci.CreditLimit = mapSAP.get('KLIMK');
                    String st = mapSAP.get('KLPRZ');    
                    cci.CreditLimitUsed = st.substring(0, st.length())+'%';
                    //cci.SAP_KUNNR__c = mapSAP.get('KUNNR');
                    cci.CountryKey = mapSAP.get('LAND1');
                    cci.Name1 = mapSAP.get('NAME1');
                    st = mapSAP.get('OBLIG');
                    cci.CreditExposure = st.substring(0, st.length());
                    cci.City = mapSAP.get('ORT01');
                    cci.Region = mapSAP.get('REGIO');
                    cci.CurrencyKey = mapSAP.get('WAERS');
            }
        }catch (Exception e) {
            System.debug('Customer Credit Info Exception:'+e);
            ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.FATAL,'Oops, please try again!');
            ApexPages.addMessage(myMsg);
        }
        return cci;
    }


/*
Wrapper for Customer Credit Info

Credit Block    
 Country Key    
Risk category   
Name    
Risk Class  
Credit exposure 
Rating  
City    
Credit Limit    
Region  
Credit limit used   
Currency Key

*/    
    public class CustomerCreditInfo {
        public String CreditBlock{get; set;} //MONTH_1
        public String CountryKey{get; set;} //UMNETWR_CUR
        public String RiskCategory{get; set;} //UMNETWR
        public String Name1 {get;set;} //UMWAVWR_CUR
        public String RiskClass{get; set;} //UMWAVWR    
        public String CreditExposure{get; set;} //UMKZWI1_CUR
        public String Rating{get;set;} //UMKZWI1
        public String City{get; set;} //MONTH_1
        public String CreditLimit{get; set;} //UMNETWR_CUR
        public String Region{get; set;} //UMNETWR
        public String CreditLimitUsed{get;set;} //UMWAVWR_CUR
        public String CurrencyKey{get; set;} //UMWAVWR    
    }

}
share|improve this question
add comment

1 Answer 1

up vote 5 down vote accepted

The right place to check what the user entered in the page is the action that runs as the result of e.g. a button click not in the class constructor. The constructor will run when the page is initially opened, but will not run on a post-back because in that case the state is re-created from the view state not by running the constructor.

If you catch an exception you are essentially saying "I've handled it just keep running the rest of the code" so the exception will propagate no further. Occasionally you may choose to do something and then re-throw if you also want some code further up the call stack to react:

try {
    ...
} catch (Exception e) {
    ....
    throw e;
}

Generally speaking adding a lot of try/catch is not a good way to go. It is better to write explicit code for the expected cases (if/else, method return values etc) and leave exceptions for unexpected conditions (where the stack trace including line numbers becomes very valuable for debugging).

share|improve this answer
    
Thanks Keith. Then what would be the scenarios to use custom exceptions then. –  Baskaran S May 2 at 15:26
1  
@BaskaranS If you are writing some logic in a separate class you might choose to throw an exception if improper values are passed to it. I'd sometimes throw an exception as the last else of an if/elseif/else chain even though that condition will not occur: future code changes mean it might and the exception well help identify the problem. (100% code coverage is not compatible with that; generally I aim for 90% or more code coverage.) So for unexpected (bug) situations in general. –  Keith C May 2 at 16:05
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.