Copy link to clipboard
Copied
We are testing our cf code which all works fine on a CF9 Windows Server 2008 machine but we are going to migrate to a CF11 Windows 2012 R2 machine. We have a test machine setup and all the code moved over and so far the cfm pages seem to work fine as well as the Application.cfc page but when we call a cfc via AJAX or we visit the cfc methods directly we get a 500.0 error Application could not be found.
Anybody else run into this?
Copy link to clipboard
Copied
I am beginning to suspect something changed in how Application.cfc works with sub directories in CF 11. I can take the .cfc I am trying to access out of the sub directory (which has it's own Application.cfc) and put it in the root directory (which has it's own Application.cfc) and it works fine. Any ideas as to why this might be?
Copy link to clipboard
Copied
Does one or the other Application.cfc have an onCFCRequest() method in it? If they both do, is the code inside the method the same?
-Carl V.
Copy link to clipboard
Copied
Neither one of the Application.cfc have that method.
Copy link to clipboard
Copied
Can you post the content of the Application.cfc file that doesn't work?
-Carl V.
Copy link to clipboard
Copied
I will do both as separate messages with some info redacted with XXXXXX. The Application.cfc in the root directory is below.
<cfcomponent
displayname="Application"
output="true"
hint="Handle the application.">
<!--- Set up the application. --->
<cfset THIS.Name = "XXXXXX" />
<cfset THIS.ApplicationTimeout = CreateTimeSpan( 2, 0, 0, 0 ) />
<cfset THIS.SessionManagement = true />
<cfset THIS.SessionTimeout = CreateTimeSpan( 0, 2, 30, 0 ) />
<cfset THIS.SetClientCookies = true />
<!--- Define the page request properties. --->
<cfsetting
requesttimeout="30"
showdebugoutput="true"
enablecfoutputonly="false"
/>
<cffunction
name="OnApplicationStart"
access="public"
returntype="boolean"
output="false"
hint="Fires when the application is first created.">
<CFQUERY NAME="GetAdmin" DATASOURCE="XXXXXX">
SELECT * FROM AdminOptions
WHERE ID = 1
</CFQUERY>
<cfset APPLICATION.DSN = "XXXXXX" />
<cfset APPLICATION.debugIPAddress = "XXXXXX" />
<cfset APPLICATION.debugIPAddress2 = "XXXXXX" />
<cfset APPLICATION.ScheduledTaskIP = "XXXXXX" />
<cfset APPLICATION.ScheduledTaskIP2 = "XXXXXX" />
<cfset APPLICATION.EncryptionKey = "XXXXXX" />
<cfset APPLICATION.AdminEmail = "XXXXXX" />
<cfset APPLICATION.NotificationEmail = #GetAdmin.mainEmail# />
<cfset APPLICATION.SiteTitle = "XXXXXX" />
<!--- urls --->
<cfset APPLICATION.SiteURL = "XXXXXX" />
<cfset APPLICATION.ImageURL = "XXXXXX" />
<cfset APPLICATION.AttachmentURL = "XXXXXX" />
<!--- directories --->
<cfset APPLICATION.BaseDirectory = "XXXXXX" />
<cfset APPLICATION.VendorUploadsDirectory = "XXXXXX\data\VendorUploads" />
<cfset APPLICATION.VendorDownloadsDirectory = "XXXXXX\www\downloads" />
<cfset APPLICATION.ImageDirectory = "XXXXXX\www\product-images" />
<cfset APPLICATION.AttachmentDirectory = "XXXXXX\www\uploads" />
<cfset APPLICATION.FeedDirectory = "XXXXXX\data" />
<cfset APPLICATION.cfcRoot = "#APPLICATION.BaseDirectory#\api">
<!--- include startup file(s) --->
<cfinclude template="includes/inc-cleanup.cfm">
<!--- Return out. --->
<cfreturn true />
</cffunction>
<cffunction
name="OnSessionStart"
access="public"
returntype="void"
output="false"
hint="Fires when the session is first created.">
<!--- Define the local scope. --->
<cfset var LOCAL = {} />
<!---
Store the CF id and token. We are about to clear the
session scope for intialization and want to make sure
we don't lose our auto-generated tokens.
--->
<cfset LOCAL.CFID = SESSION.CFID />
<cfset LOCAL.CFTOKEN = SESSION.CFTOKEN />
<!--- Clear the session. --->
<cfset StructClear( SESSION ) />
<!---
Replace the id and token so that the ColdFusion
application knows who we are.
--->
<cfset SESSION.CFID = LOCAL.CFID />
<cfset SESSION.CFTOKEN = LOCAL.CFTOKEN />
<!--- Assigns and passes shopping cart ID. Do not change! --->
<CFINCLUDE TEMPLATE="includes/inc-session-id.cfm">
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction
name="OnRequestStart"
access="public"
returntype="boolean"
output="false"
hint="Fires at first part of page processing.">
<!--- Define ARGUMENTS. --->
<cfargument
name="TargetPage"
type="string"
required="true"
/>
<!--- Define the local scope. --->
<cfset var local = {} />
<!--- Assigns and passes shopping cart ID. Do not change! --->
<CFINCLUDE TEMPLATE="includes/inc-session-id.cfm">
<!--- Get requested URL from request object. --->
<cfset prevURL = #CGI.HTTP_REFERER# />
<!--- Check for reinitialization. --->
<cfif StructKeyExists( URL, "reset" )>
<!--- Reset application and session. --->
<cfset THIS.OnApplicationStart() />
<cfset THIS.OnSessionStart() />
</cfif>
<cfif structKeyExists( url, "logout" )>
<!--- Change the timeout on the current session scope. This is an undocumented function. We are changing it to one second. --->
<cfset session.setMaxInactiveInterval(javaCast("long", 1)) />
<!--- Clear all of the session cookies. This will expire them on the user's computer when the CFLocation executes.
NOTE: We need to do this so that the redirect
doesn't immediately pick up the previous session
within the new, one-second timeout (which would
completely defeat our purpose).
--->
<cfloop index="local.cookieName" list="cfid,cftoken,cfmagic">
<!--- Expire this session cookies --->
<cfcookie name="#local.cookieName#" value="" expires="now" />
</cfloop>
<!---
Redirect back to the primary page (so that we dont
have the killSession URL parameter visible).
--->
<cflocation url="./index.cfm" addtoken="false" />
</cfif>
<!--- Return out. --->
<cfreturn true />
</cffunction>
<cffunction
name="OnRequest"
access="public"
returntype="void"
output="true"
hint="Fires after pre page processing is complete.">
<!--- Define ARGUMENTS. --->
<cfargument
name="PageRequestedByUser"
type="string"
required="true"
/>
<cfif (isDefined("SESSION.Vendor.ID") AND SESSION.Vendor.ID NEQ 0)>
<cfif isDefined("SESSION.SessionID")>
<!--- lookup cart total --->
<cfquery name="GetCartTotal" datasource="#APPLICATION.DSN#">
SELECT SUM(Cart.Price * Cart.Quantity) AS CurrCartTotal FROM Cart
WHERE Cart.SessionID = <cfqueryparam cfsqltype="cf_sql_integer" value="#SESSION.SessionID#"> AND Cart.CustomerID = <cfqueryparam cfsqltype="cf_sql_integer" value="#SESSION.Vendor.ID#"> AND (Status = 'Shopping' OR Status = 'Saved')
</cfquery>
</cfif>
<!--- User logged in. Allow page request. --->
<cfinclude template="#ARGUMENTS.PageRequestedByUser#" />
<cfelseif FindNoCase("request-catalog.cfm", ARGUMENTS.PageRequestedByUser)>
<!--- User requested catalog. --->
<cfinclude template="request-catalog.cfm" />
<cfelse>
<!---
User is not logged in - include the login page regardless of what was requested.
--->
<cfinclude template="login.cfm" />
</cfif>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction
name="OnRequestEnd"
access="public"
returntype="void"
output="true"
hint="Fires after the page processing is complete.">
<!--- dump out the session to the screen --->
<cfif CGI.REMOTE_ADDR IS APPLICATION.debugIPAddress>
<cfdump var="#SESSION#">
</cfif>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction
name="OnSessionEnd"
access="public"
returntype="void"
output="false"
hint="Fires when the session is terminated.">
<!--- Define ARGUMENTS. --->
<cfargument
name="SessionScope"
type="struct"
required="true"
/>
<cfargument
name="ApplicationScope"
type="struct"
required="false"
/>
<!--- session cleanup code here --->
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction
name="OnApplicationEnd"
access="public"
returntype="void"
output="false"
hint="Fires when the application is terminated.">
<!--- Define ARGUMENTS. --->
<cfargument
name="ApplicationScope"
type="struct"
required="false"
default="#StructNew()#"
/>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction name="onError">
<!--- The onError method gets two arguments:
An exception structure, which is identical to a cfcatch variable.
The name of the Application.cfc method, if any, in which the error
happened. --->
<cfargument name="Except" required = true />
<cfargument type="String" name = "EventName" required = true />
<!--- Log all errors in an application-specific log file. --->
<!---
<cflog file="#This.Name#" type="error" text="Event Name: #Eventname#" >
<cflog file="#This.Name#" type="error" text="Message: #except.message#">
--->
<!--- Throw validation errors to ColdFusion for handling. --->
<cfif Find("coldfusion.filter.FormValidationException", Arguments.Except.StackTrace)>
<cfthrow object="#except#">
<cfelse>
<!--- You can replace this cfoutput tag with application-specific error-handling code. --->
<cfif #CGI.REMOTE_ADDR# IS #APPLICATION.debugIPAddress#>
<p>Error Event: #EventName#</p>
<cfif isDefined("SESSION.Vendor.ID")><p>Member ID: #SESSION.Vendor.ID#</p></cfif>
<cfif isDefined("ID")><p>ID Posted: #ID#</p></cfif>
<p>Error details:<br><cfdump var="#except#"></p>
<p>Application vars:<br><cfdump var="#Application#"></p>
<p>Session vars:<br><cfdump var="#SESSION#"></p>
<p>CGI vars:<br><cfdump var="#cgi#"></p>
<p>FORM vars:<br><cfdump var="#FORM#"></p>
<p>URL vars:<br><cfdump var="#URL#"></p>
<cfmail TO="#APPLICATION.AdminEmail#" FROM="#APPLICATION.AdminEmail#" SUBJECT="#APPLICATION.SiteTitle# Exception Error" TYPE="HTML">
<p>Error Event: #EventName#</p>
<cfif isDefined("SESSION.Vendor.ID")><p>Member ID: #SESSION.Vendor.ID#</p></cfif>
<cfif isDefined("ID")><p>ID Posted: #ID#</p></cfif>
<p>Error details:<br><cfdump var="#except#"></p>
<p>Application vars:<br><cfdump var="#Application#"></p>
<p>Session vars:<br><cfdump var="#SESSION#"></p>
<p>CGI vars:<br><cfdump var="#cgi#"></p>
<p>FORM vars:<br><cfdump var="#FORM#"></p>
<p>URL vars:<br><cfdump var="#URL#"></p>
</cfmail>
<cfelse>
<cfmail TO="#APPLICATION.AdminEmail#" FROM="#APPLICATION.AdminEmail#" SUBJECT="#APPLICATION.SiteTitle# Exception Error" TYPE="HTML">
<p>Error Event: #EventName#</p>
<cfif isDefined("SESSION.Vendor.ID")><p>Member ID: #SESSION.Vendor.ID#</p></cfif>
<cfif isDefined("ID")><p>ID Posted: #ID#</p></cfif>
<p>Error details:<br><cfdump var="#except#"></p>
<p>Application vars:<br><cfdump var="#Application#"></p>
<p>Session vars:<br><cfdump var="#SESSION#"></p>
<p>CGI vars:<br><cfdump var="#cgi#"></p>
<p>FORM vars:<br><cfdump var="#FORM#"></p>
<p>URL vars:<br><cfdump var="#URL#"></p>
</cfmail>
<cfinclude template="error.cfm" />
</cfif>
</cfif>
</cffunction>
</cfcomponent>
Copy link to clipboard
Copied
I'll wait until you post the other Application.cfc to see if there is a significant difference that would account for the behavior you are seeing. However, I did not that in your onSessionStart() method, you do a var LOCAL= {} at the top of the function. This should not be done post-CF8, as Adobe introduced an actual "local" scope to functions in CF9. Defining a LOCAL variable will actually result in the creation of a "local" structure key within the "local" scope (aka "local.local"). This may result in unintended side effects.
Also, there was an issue with handling CFCs in the OnRequest method in CF9 and CF10 (I think the onCFCRequest method was introduced to remedy the issue). The recommendation I received was to examine the TargetPage argument of onRequestStart, and if it was a CFC, remove the onRequest method from the CFC instance. Here is a sample fragment from the onRequestStart method of one of my CFC's:
<!--- If the TargetPage is a CFC, its a web service request and
the request scope must be removed in order for the web
service to properly return data to the requestor. Also,
disable debugging --->
<cfif LCase(Right(ARGUMENTS.TargetPage,3)) EQ "cfc">
<cfset StructDelete(THIS,"OnRequest")>
<cfsetting showdebugoutput="no">
</cfif>
HTH,
-Carl V.
Copy link to clipboard
Copied
Oops, I should have waited longer to reply. So you do have the logic to remove the CFC requests in your subfolder Application.cfc. But I think the logic in your <CFIF> statement may be flawed. You have:
<cfif right(arguments.targetPage,4) is "Orders.cfc">
which is comparing the last 4 characters of arguments.targetPage to "Orders.cfc", which will never match and thus the onRequest() method will never be deleted. I think you want this instead:
<cfif right(arguments.targetPage,4) is ".cfc">
Even better, add in some handling for case sensitivity:
<cfif lcase(right(arguments.targetPage,4)) is ".cfc">
HTH,
-Carl V.
Copy link to clipboard
Copied
First off thanks for the help. It is much appreciated. Since there is now an onCFCRequest() should I just replace the <cfif lcase(right(arguments.targetPage,4)) is ".cfc"> with this method instead?
I was not aware of the LOCAL changes to session so I will also make these adjustments and see what errors I get
Copy link to clipboard
Copied
I can only say try it and see. I haven't used onCFCRequest() yet, and the documentation on it isn't that great. This Ben Nadel blog post might be more helpful.
Just to clarify the "local" issue a bit: starting with CF9, there is a "local" scope available inside functions, and variables placed in that "local" scope are private to the function. You can access it much the same way you used to access it before when you created a "local" variable (thru var local=StructNew() or var local={} ), except you don't have to define it to start with. So just eliminate the var local= statement entirely. Any variable you define in a function using the <cfset local.someVariableName="someValue"> pattern will be put in the "local" scope. Alternatively, if you define a variable using the "var" keyword (like <cfset var someVariableName="someValue"), it will be put in the function's "local" scope. Any variable you define without doing either of the above will be placed in the component's "variables" scope and will be shared by any method within the component.
LOCAL and SESSION are two completely different things, though, so don't confuse them. There is some code in one of your App.cfc that copies the SESSION token and id variables into LOCAL variables, then puts them back. Depending on the reasons for that code, you'll need to still do that. You just don't need to start that function with <cfset var local={}> anymore.
I also don't think you ever needed to remove onRequestEnd() for CFCs, only onRequest(). From Ben Nadel's post, if you add an onCFCRequest() function to your App.cfc, it appears you don't even need to remove onRequest() anymore, as ColdFusion will route CFC requests automatically to onCFCRequest() rather than onRequest().
-Carl V.
Copy link to clipboard
Copied
Now this is the Application.cfc from the sub directory folder named /api that contains my .cfcs so when I try to access the cfc in that sub directory I get that 500 error. If I move the cfc to the root directory the cfc executes like it should.
<cfcomponent
displayname="Application"
output="true"
hint="Handle the application.">
<!--- Set up the application. --->
<cfset THIS.Name = "XXXXXX" />
<cfset THIS.ApplicationTimeout = CreateTimeSpan( 2, 0, 0, 0 ) />
<cfset THIS.SessionManagement = true />
<cfset THIS.SessionTimeout = CreateTimeSpan( 0, 2, 30, 0 ) />
<cfset THIS.SetClientCookies = true />
<!--- Define the page request properties. --->
<cfsetting
requesttimeout="30"
showdebugoutput="true"
enablecfoutputonly="false"
/>
<cffunction
name="OnApplicationStart"
access="public"
returntype="boolean"
output="false"
hint="Fires when the application is first created.">
<CFQUERY NAME="GetAdmin" DATASOURCE="XXXXXX">
SELECT * FROM AdminOptions
WHERE ID = 1
</CFQUERY>
<cfset APPLICATION.DSN = "XXXXXX" />
<cfset APPLICATION.debugIPAddress = "XXXXXX" />
<cfset APPLICATION.debugIPAddress2 = "XXXXXX" />
<cfset APPLICATION.ScheduledTaskIP = "XXXXXX" />
<cfset APPLICATION.ScheduledTaskIP2 = "XXXXXX" />
<cfset APPLICATION.EncryptionKey = "XXXXXX" />
<cfset APPLICATION.AdminEmail = "XXXXXX" />
<cfset APPLICATION.NotificationEmail = #GetAdmin.mainEmail# />
<cfset APPLICATION.SiteTitle = "XXXXXX" />
<!--- urls --->
<cfset APPLICATION.SiteURL = "XXXXXX" />
<cfset APPLICATION.ImageURL = "XXXXXX" />
<cfset APPLICATION.AttachmentURL = "XXXXXX" />
<!--- directories --->
<cfset APPLICATION.BaseDirectory = "XXXXXX" />
<cfset APPLICATION.VendorUploadsDirectory = "XXXXXX\data\VendorUploads" />
<cfset APPLICATION.VendorDownloadsDirectory = "XXXXXX\www\downloads" />
<cfset APPLICATION.ImageDirectory = "XXXXXX\www\product-images" />
<cfset APPLICATION.AttachmentDirectory = "XXXXXX\www\uploads" />
<cfset APPLICATION.FeedDirectory = "XXXXXX\data" />
<cfset APPLICATION.cfcRoot = "#APPLICATION.BaseDirectory#\api">
<!--- Return out. --->
<cfreturn true />
</cffunction>
<cffunction
name="OnSessionStart"
access="public"
returntype="void"
output="false"
hint="Fires when the session is first created.">
<!--- Define the local scope. --->
<cfset var LOCAL = {} />
<!---
Store the CF id and token. We are about to clear the
session scope for intialization and want to make sure
we don't lose our auto-generated tokens.
--->
<cfset LOCAL.CFID = SESSION.CFID />
<cfset LOCAL.CFTOKEN = SESSION.CFTOKEN />
<!--- Clear the session. --->
<cfset StructClear( SESSION ) />
<!---
Replace the id and token so that the ColdFusion
application knows who we are.
--->
<cfset SESSION.CFID = LOCAL.CFID />
<cfset SESSION.CFTOKEN = LOCAL.CFTOKEN />
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction
name="OnRequestStart"
access="public"
returntype="boolean"
output="false"
hint="Fires at first part of page processing.">
<!--- Define arguments. --->
<cfargument
name="TargetPage"
type="string"
required="true"
/>
<!--- Check for initialization. --->
<cfif StructKeyExists( URL, "reset" )>
<!--- Reset application and session. --->
<cfset THIS.OnApplicationStart() />
<cfset THIS.OnSessionStart() />
</cfif>
<!---
Check to see if the target page is in the web services
directory. If it is, then we want to delete the OnRequest
event handler so the web service has access
--->
<cfif right(arguments.targetPage,4) is "Orders.cfc">
<!--- Delete the on request event handler. --->
<cfset StructDelete( THIS, "OnRequest" ) />
<!--- Delete the on request end handler. --->
<cfset StructDelete( THIS, "OnRequestEnd" ) />
</cfif>
<!--- Return out. --->
<cfreturn true />
</cffunction>
<cffunction
name="OnRequest"
access="public"
returntype="void"
output="true"
hint="Fires after pre page processing is complete.">
<!--- Define arguments. --->
<cfargument
name="PageRequestedByUser"
type="string"
required="true"
/>
<cfif (isDefined("SESSION.Admin.ID") AND SESSION.Admin.ID NEQ 0) OR (CGI.REMOTE_ADDR EQ APPLICATION.debugIPAddress) OR (CGI.REMOTE_ADDR EQ APPLICATION.debugIPAddress2)>
<!--- User logged in. Allow page request. --->
<cfinclude template="#ARGUMENTS.PageRequestedByUser#" />
<cfelse>
<!---
User is not allowed
--->
<cfabort>
</cfif>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction
name="OnRequestEnd"
access="public"
returntype="void"
output="true"
hint="Fires after the page processing is complete.">
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction
name="OnSessionEnd"
access="public"
returntype="void"
output="false"
hint="Fires when the session is terminated.">
<!--- Define arguments. --->
<cfargument
name="SessionScope"
type="struct"
required="true"
/>
<cfargument
name="ApplicationScope"
type="struct"
required="false"
default="#StructNew()#"
/>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction
name="OnApplicationEnd"
access="public"
returntype="void"
output="false"
hint="Fires when the application is terminated.">
<!--- Define arguments. --->
<cfargument
name="ApplicationScope"
type="struct"
required="false"
default="#StructNew()#"
/>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction name="onError">
<!--- The onError method gets two arguments:
An exception structure, which is identical to a cfcatch variable.
The name of the Application.cfc method, if any, in which the error
happened. --->
<cfargument name="Except" required = true />
<cfargument type="String" name = "EventName" required = true />
<!--- Log all errors in an application-specific log file. --->
<!---
<cflog file="#This.Name#" type="error" text="Event Name: #Eventname#" >
<cflog file="#This.Name#" type="error" text="Message: #except.message#">
--->
<!--- Throw validation errors to ColdFusion for handling. --->
<cfif Find("coldfusion.filter.FormValidationException", Arguments.Except.StackTrace)>
<cfthrow object="#except#">
<cfelse>
<!--- You can replace this cfoutput tag with application-specific error-handling code. --->
<cfif #CGI.REMOTE_ADDR# IS #APPLICATION.debugIPAddress#>
<p>Error Event: #EventName#</p>
<cfif isDefined("SESSION.Member.ID")><p>Member ID: #SESSION.Member.ID#</p></cfif>
<cfif isDefined("ID")><p>ID Posted: #ID#</p></cfif>
<p>Error details:<br><cfdump var="#except#"></p>
<p>Application vars:<br><cfdump var="#Application#"></p>
<p>CGI vars:<br><cfdump var="#cgi#"></p>
<p>FORM vars:<br><cfdump var="#FORM#"></p>
<p>URL vars:<br><cfdump var="#URL#"></p>
<cfmail TO="#APPLICATION.AdminEmail#" FROM="#APPLICATION.AdminEmail#" SUBJECT="#APPLICATION.SiteTitle# Exception Error" TYPE="HTML">
<p>Error Event: #EventName#</p>
<cfif isDefined("SESSION.Member.ID")><p>Member ID: #SESSION.Member.ID#</p></cfif>
<cfif isDefined("ID")><p>ID Posted: #ID#</p></cfif>
<p>Error details:<br><cfdump var="#except#"></p>
<p>Application vars:<br><cfdump var="#Application#"></p>
<p>CGI vars:<br><cfdump var="#cgi#"></p>
<p>FORM vars:<br><cfdump var="#FORM#"></p>
<p>URL vars:<br><cfdump var="#URL#"></p>
</cfmail>
<cfelse>
<cfmail TO="#APPLICATION.AdminEmail#" FROM="#APPLICATION.AdminEmail#" SUBJECT="#APPLICATION.SiteTitle# Exception Error" TYPE="HTML">
<p>Error Event: #EventName#</p>
<cfif isDefined("SESSION.Member.ID")><p>Member ID: #SESSION.Member.ID#</p></cfif>
<cfif isDefined("ID")><p>ID Posted: #ID#</p></cfif>
<p>Error details:<br><cfdump var="#except#"></p>
<p>Application vars:<br><cfdump var="#Application#"></p>
<p>CGI vars:<br><cfdump var="#cgi#"></p>
<p>FORM vars:<br><cfdump var="#FORM#"></p>
<p>URL vars:<br><cfdump var="#URL#"></p>
</cfmail>
<cfinclude template="error.cfm" />
</cfif>
</cfif>
</cffunction>
</cfcomponent>
Copy link to clipboard
Copied
Funny you should mention that the issue is inside an /api folder. I'm trying to track down the same problem, except I'm directly accessing an index.cfm (sort of -- onRequest intercepts the request and redirects to CFCs as appropriate -- it's a Taffy API) and I've found that renaming the folder from /api to ... literally anything else... works fine. It's almost as if something in CF has special meaning at /api, like the special /rest mapping does.
Copy link to clipboard
Copied
I found the root cause: CF11 added a servlet mapping for /api that's interfering with your request:
ColdFusion 11 Sometimes Chokes on /api • FusionGrokker
You can comment it out in web.xml, or change your folder name to something other than /api.
Copy link to clipboard
Copied
Adding a bit more about this solution to the problem, first about Adam's last post, the URL he offered no longer works, but here is the page from the web archive:
Second, in case it may help others to find this (since his old post no longer shows up in search engines), you can also tell this is happening because you may see an error in your CF application.log (and coldfusion-out.log) about "Application could not be found", if your request is for a folder called /api which you have but (as of CF11) CF is looking instead for a REST service registered in the CF Admin or application.cfc and is finding none. Of if you have a subfolder like /api/whatever/ the error might say "application whatever could not be found").
And as Adam's post noted, you could also find more detail on the problem (and the reference to CF's restservlet) in the CF's exception.log.
He proposes one solution is to rename your web site's /api folder to another name (which he acknowledges can have problems), or he shows editing CF's web.xml and comment out its reference to /api if you don't use CF's rest feature. I'll add a clarification that there are multiple web.xml files in CF: he meant the one in cfusion/wwwroot/WEB-INF/web.xml (of change cfusion to instancename if using CF's multiple instances feature). And I'll add a recommendation that you backup that file before touching it, in case you make a mistake and need to quickly recover.
Finally, as an update, note that CF2018 did change that internal path to instead be /restapps, so folks using /api for web site folder names would no longer hit this problem. It's only those on CF11 and 2016.
Copy link to clipboard
Copied
I would research how to turn on detailed error reporting, even if it's only temporary. This will better pinpoint the error. IIS by default intercepts all errors, suppresses any details, and spits out an error 500. Another problem I have seen to cause 500 errors is having an error trap the throws a secondary error. To eliminate this possibility I comment out all CFERROR tags and onError application functions.
Copy link to clipboard
Copied
To turn on detailed error reporting,
Uncheck the “Enable HTTP status codes” under Settings inside CF Admin. This will give you CF related error.
Regards,
Anit Kumar