function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Roger WickiRoger Wicki 

Split string returns empty list

Hi Community

I am sure I have had this one before, but no clue on how I solved it if I didn't try a different approach. So the problem is that the String.split() function returns an empty list<String> resp. an empty String[].

This is the code part I'm speaking about:
// oli is a OpportunityLineItem
// ProductFamily__c is a formula and contains:
// TEXT({!PricebookEntry.Product2.Family}) + " - " + TEXT({!PricebookEntry.Product2.SubType__c})
// where SubType__c is a dependent picklist of Family
// COST_UNIT_MAP is a map<String, String> that is already initialised and filled with lots of values

oli.ProductFamily__c != NULL && COST_UNIT_MAP.containsKey(oli.ProductFamily__c.split(' - ').get(0))

This is called in an if statement surrounded by a try block which catches a NullPointerException (complete code of the function below). But the error thrown is a "ListIndexOutOfBounds: 0". I have never seen a split function return an empty list before. Because that's what must happen, otherwise I would not get that error. If I were to call split() on null, it'd throw a null pointer exception. If I use it on any string (even an empty one) i would get that string at least as the first entry in the list. An empty String is also really unprobably because Salesforce saves everything that does not contain a value as null.

Anyone got any idea on what's going on here?

Thanks in advance
Roger


The whole function:
    private void assignCostUnit() {
		try {
			String errorMessage;
			for ( OpportunityLineItem oli : olis ) {
				if ( oli.ProductFamily__c != NULL && COST_UNIT_MAP.containsKey(oli.ProductFamily__c) ) {
					oli.CostUnit__c = COST_UNIT_MAP.get(oli.ProductFamily__c);
				}
				else if ( oli.ProductFamily__c != NULL && COST_UNIT_MAP.containsKey(oli.ProductFamily__c.split(' - ').get(0)) ) {
					oli.CostUnit__c = COST_UNIT_MAP.get(oli.ProductFamily__c.split(' - ').get(0));
				} else {
					errorMessage = (errorMessage != NULL && !errorMessage.equals('') ? (errorMessage + '\nprodFam: ' + oli.ProductFamily__c + ', costUnit: ' + oli.CostUnit__c) : 
									('prodFam: ' + oli.ProductFamily__c + ', costUnit: ' + oli.CostUnit__c));
					system.debug(LoggingLevel.INFO, errorMessage);
				}
			}
			if ( errorMessage != NULL && !errorMessage.equals('') ) {
				ArcUtil.sendAdminNotification(errorMessage);
			}
		} catch(system.NullPointerException npe) {
			String errorMessage = 'Could not assign cost unit. The splitting of the Product Family on Opportunity Line Item with \" - \" failed. Check if the Product Family is ' +
									'not empty\n' + npe.getCause() + '\n' + npe.getStackTraceString();
			system.debug(LoggingLevel.ERROR, errorMessage);
			ArcUtil.sendAdminNotification(errorMessage);
		}
	}

 
Best Answer chosen by Roger Wicki
Roger WickiRoger Wicki
Okay I found the problem. Apparently, the problem was, that for the OpportunityLineItem no PricebookEntry was defined at the time this code got executed. This meant the formula for ProductFamily__c was composed of only " - ". If you split this string by " - " you apparently receive an empty list (though I still think it should give you a list with two empty strings in it...)

All Answers

Roger WickiRoger Wicki
Okay I found the problem. Apparently, the problem was, that for the OpportunityLineItem no PricebookEntry was defined at the time this code got executed. This meant the formula for ProductFamily__c was composed of only " - ". If you split this string by " - " you apparently receive an empty list (though I still think it should give you a list with two empty strings in it...)
This was selected as the best answer
Ravi Dutt SharmaRavi Dutt Sharma
Hey Roger,

A question here. Are you even suppose to catch Runtime exceptions, like the NPE you are catching in your code.
Roger WickiRoger Wicki
Hi Ravi

I generally do it because you can provide more information for debugging once an error happens i.e. you could add more information on the location of the error thrown and/or do a different process if an error is caught. I personally like to show the user causing the error to have a readable error message and especially if it's not a user caused error, send myself an email with more details (StackTrace, Module of code, etc.)