I have a function in my company’s site that uses the cgi.remote_host variable to call an API provided by hostip.info and return the country of orgin. The way this is supposed to work is:
- the function finds the country from the API,
- runs a query against our local database to determine which site we are going to forward
the user to, and - redirects the user to the appropriate site.
If for any reason, we can’t associate a country with one of our regions, we redirect the user to a default site.
What actually happens is that, occasionally, our server cannot locate the API and we get a timeout error.
This is a proxy of the function we’re calling to get the territory:
<cffunction name="getGeoInfo" access="public" output="true" returntype="any" hint="call getGeoIP API and check country against DB">
<cfargument name="IPAddress" required="yes" type="string" />
<!--- Calling hostip API to get our Geo IP information --->
<cfhttp url="http://api.hostip.info/?ip=#arguments.IPAddress#" method="get" result="geoIP" />
<!--- Try to parse the file, if it can't parse, we don't create the variable --->
<cftry>
<cfset geoIPXML = xmlParse(geoIP.fileContent) />
<cfcatch type="any" />
</cftry>
<!--- If variable was created, perform the function to get territory info --->
<cfif isDefined("geoIPXML")>
<cfset countryAbbrev = geoIPXML.HostipLookupResultSet['gml:featureMember']['hostip']['countryabbrev'].xmlText />
<cfquery name="theTerritory" datasource="#request.dsource#">
SELECT territory
FROM countries
WHERE countryCode = <cfqueryparam value="#countryAbbrev#" cfsqltype="cf_sql_varchar" />
</cfquery>
<!--- If no record was found, set locale to default --->
<cfif theTerritory.recordcount EQ 0>
<cfset returnLocale = "default" />
<cfelse>
<!--- Otherwise set it to territory found in DB --->
<cfset returnLocale = theTerritory.territory />
</cfif>
<cfelse>
<!--- if no XML file was returned, set locale to default --->
<cfset returnLocale="default" />
</cfif>
<cfreturn returnLocale />
</cffunction>
What am I missing here? How should I change this function so that if the http request times out, that I still return my default?
Wrap the
<cfhttp>call in<cftry>.Also, I would have the catch block just return the defaultLocale rather than do nothing and then check for the existence of geoIPXML.