I use UDFs (user defined functions) frequently in my coding. One recent function I wrote got me thinking about the importance of validating the data that is passed to the function as an argument.

The simplest validation is already handled by ColdFusion. When defining an argument, you can specify the expected type for the argument data by using the type attribute:

view plain print about
1<cfargument name="foo" type="date" required="true" hint="The date bar was created.">

If the value of foo is not a date recognizable by CF an exception is automatically thrown.

Data validation, however, should go beyond this type of simple check. The function should ensure that the argument value meets the logical needs, the business requirements, of the function.

Let's start with a simple UDF called isWeekend that takes a single argument for the day of week. If the day of week is a Sunday or Saturday, the UDF returns true. (Yes, this is a US-biased example.)

view plain print about
1<cffunction name="isWeekend" output="false" returntype="boolean" hint="Determines if the day is on the weekend.">
2    <cfargument name="dayOfWeek" type="numeric" required="true">
3    
4    <cfset var local = structNew()>
5    <cfset local.result = false>
6    
7    <cfif listFind("1,7", arguments.dayOfWeek)>
8        <cfset local.result = true>
9    </cfif>
10    
11    <cfreturn local.result>
12</cffunction>

If we attempt to pass a non-numeric value in dayOfWeek, CF will throw an error. However, if we call the function as isWeekend(17), CF will happily process the function logic since 17 is a valid number. In fact, we can even call the function as isWeekend(200.25) with no problems. Of course, there is no 200.25th day of the week, but ColdFusion simply checks for a valid number.

Let's give the UDF a little more awareness, and user-friendliness, by checking that the passed in data actually makes logical sense:

view plain print about
1<cffunction name="isWeekend" output="false" returntype="boolean" hint="Determines if the day is on the weekend.">
2    <cfargument name="dayOfWeek" type="numeric" required="true">
3    
4    <cfset var local = structNew()>
5    <cfset local.result = false>
6    
7    <!--- A week has seven days, so make sure the day of week falls within that range. --->
8    <cfif NOT reFind("[1-7]", arguments.dayOfWeek)>
9        <cfthrow message="The day of week to check must be a number between 1 and 7.">
10    </cfif>
11    
12    <cfif listFind("1,7", arguments.dayOfWeek)>
13        <cfset local.result = true>
14    </cfif>
15    
16    <cfreturn local.result>
17</cffunction>

The addition of the data check helps the user of the isWeekend UDF pass in logical data. It also helps when testing to provide parameters for testing edge cases.

Argument data validation is not needed, or even desirable, in all situations. Ultimately the need is often dictated by your business requirements. However, data validation beyond that provided by ColdFusion, through the type attribute of the cfargument tag, makes a UDF more user-friendly, as well as more defensive.