Hi all, I have another weird issue today with file...
# cfml-general
j
Hi all, I have another weird issue today with file paths that I'd like to talk about. (Today I won't show any sensitive info though, lol). On our new server, our application throws the folllowing error upon running its
onSessionEnd()
function:
Copy code
Error type:
Builder.BuildCFCDependencyException

Error message:
Error building: handlers.Main -> Could not find the included template //includes/helpers/ApplicationHelper.cfm.
					Note: If you wish to use an absolute template path (for example, template="/mypath/index.cfm") with include, you must create a mapping for the path using the ColdFusion Administrator. Or, you can use per-application settings to specify mappings specific to this application by specifying a mappings struct to THIS.mappings in Application.cfc. <br> Using relative paths (for example, template="index.cfm" or template="../index.cfm") does not require the creation of any special mappings. It is therefore recommended  that you use relative paths with include whenever possible.. | DSL: , Path: handlers.Main,
//includes/helpers/ApplicationHelper.cfm
is not a valid path to my
ApplicationHelper.cfm
file, as it adds and extra two forward slashes to the start of the correct path, so I went to my
coldbox.cfc
file to see if I could change the path, and found this within the coldbox struct:
applicationHelper        : "includes/helpers/ApplicationHelper.cfm"
So it looks like something is appending two forward slashes to the path somewhere, but I'm not sure where. It is also relevant to mention that this error does not throw in our development environment. It just started with our production environment. Does anyone have advice for troubleshooting this? Thanks for all the help y'all have given me so far!
āž• 1
āœ… 1
c
Where is the error originating from? ColdBox/WireBox or your own code in
onSessionEnd()
? Maybe show the
onSessionEnd()
code. And a stack trace, if available.
j
Hi! It looks like the error is coming from coldbox, but it does trigger once a session is ended. The trace begins at where the `application.cfc`'s
onSessionEnd()
function is called. Here's the
onSessionEnd()
from
application.cfc
:
Copy code
public void function onSessionEnd( struct sessionScope, struct appScope ) {
		try
		{
			arguments.appScope.cbBootStrap.onSessionEnd( argumentCollection = arguments);
		}
		catch(any e)
		{
			var appPath = getDirectoryFromPath( getCurrentTemplatePath() );
			fileAppend( "#appPath#/logs/application-cfc-errors.log", "Error @#getHTTPTimeString(now())#: " & e.type & " | " & e.message & " | " & e.detail & "|" & serializeJSON(e.tagContext));
			//Write the error to the console
			writeDump(
				var = "Error @#getHTTPTimeString(now())#: " & e.type & " | " & e.message & " | " & e.detail & "|" & serializeJSON(e.tagContext),
				output = "console"
			);
		}
	}
Here is the trace:
Copy code
webroot\coldbox\system\FrameworkSupertype.cfc:722
webroot\coldbox\system\FrameworkSupertype.cfc:744
webroot\coldbox\system\EventHandler.cfc:63|[{"RAW_TRACE":"\tat cfBuilder2ecfc1352572539$funcBUILDCFC.runFunction(webroot\\coldbox\\system\\ioc\\Builder.cfc:242)","LINE":242,"COLUMN":0,"TEMPLATE":"webroot\\coldbox\\system\\ioc\\Builder.cfc","ID":"CFTHROW","TYPE":"CFML"},{"RAW_TRACE":"\tat cfInjector2ecfc113679728$funcBUILDINSTANCE.runFunction(webroot\\coldbox\\system\\ioc\\Injector.cfc:537)","LINE":537,"COLUMN":0,"TEMPLATE":"webroot\\coldbox\\system\\ioc\\Injector.cfc","ID":"CF_TEMPLATEPROXY","TYPE":"CFML"},{"RAW_TRACE":"\tat cfNoScope2ecfc1322277262$funcGETFROMSCOPE.runFunction(webroot\\coldbox\\system\\ioc\\scopes\\NoScope.cfc:43)","LINE":43,"COLUMN":0,"TEMPLATE":"webroot\\coldbox\\system\\ioc\\scopes\\NoScope.cfc","ID":"CF_TEMPLATEPROXY","TYPE":"CFML"},{"RAW_TRACE":"\tat cfInjector2ecfc113679728$funcGETINSTANCE.runFunction(webroot\\coldbox\\system\\ioc\\Injector.cfc:508)","LINE":508,"COLUMN":0,"TEMPLATE":"webroot\\coldbox\\system\\ioc\\Injector.cfc","ID":"CF_TEMPLATEPROXY","TYPE":"CFML"},{"RAW_TRACE":"\tat cfHandlerService2ecfc2003911211$funcNEWHANDLER.runFunction(webroot\\coldbox\\system\\web\\services\\HandlerService.cfc:107)","LINE":107,"COLUMN":0,"TEMPLATE":"webroot\\coldbox\\system\\web\\services\\HandlerService.cfc","ID":"CF_TEMPLATEPROXY","TYPE":"CFML"},{"RAW_TRACE":"\tat cfHandlerService2ecfc2003911211$funcGETHANDLER.runFunction(webroot\\coldbox\\system\\web\\services\\HandlerService.cfc:144)","LINE":144,"COLUMN":0,"TEMPLATE":"webroot\\coldbox\\system\\web\\services\\HandlerService.cfc","ID":"CF_UDFMETHOD","TYPE":"CFML"},{"RAW_TRACE":"\tat cfController2ecfc453873441$func_RUNEVENT.runFunction(webroot\\coldbox\\system\\web\\Controller.cfc:762)","LINE":762,"COLUMN":0,"TEMPLATE":"webroot\\coldbox\\system\\web\\Controller.cfc","ID":"CF_TEMPLATEPROXY","TYPE":"CFML"},{"RAW_TRACE":"\tat cfController2ecfc453873441$funcRUNEVENT.runFunction(webroot\\coldbox\\system\\web\\Controller.cfc:658)","LINE":658,"COLUMN":0,"TEMPLATE":"webroot\\coldbox\\system\\web\\Controller.cfc","ID":"CF_UDFMETHOD","TYPE":"CFML"},{"RAW_TRACE":"\tat cfBootstrap2ecfc1223334166$funcONSESSIONEND.runFunction(webroot\\coldbox\\system\\Bootstrap.cfc:603)","LINE":603,"COLUMN":0,"TEMPLATE":"webroot\\coldbox\\system\\Bootstrap.cfc","ID":"CF_TEMPLATEPROXY","TYPE":"CFML"},{"RAW_TRACE":"\tat cfApplication2ecfc1789641650$funcONSESSIONEND.runFunction(webroot\\Application.cfc:74)","LINE":74,"COLUMN":0,"TEMPLATE":"webroot\\Application.cfc","ID":"CF_TEMPLATEPROXY","TYPE":"CFML"}]
t
it looks like it is reading it as an absolute path (which it is) change it to applicationHelper : "./includes/helpers/ApplicationHelper.cfm"
j
Thanks for the reply! That seems like a good idea! I'll change the path to your suggestion and let you know if it worked šŸ™‚
b
I would expect the leading forward slash to be necessary as it's a relative path (as is any path used in cfinclude)
No telling how it work on dev, prolly on accident basad on the working directory of the server or something.
Also, you really don't need the "dot" in paths in CFML. That's a bash thing that Java will play along with, but is never really neccessary.
i.e.
/foo
is a valid path, you don't need
./foo
šŸ™Œ 1
j
Thanks for chiming in Brad! That makes sense.
So I just checked my error logs and putting the
./
at the front of the path did not do the trick. Here's the new error message:
Copy code
Error @Fri, 21 Apr 2023 14:24:01 GMT: Builder.BuildCFCDependencyException | Error building: handlers.Main -> Could not find the included template //./includes/helpers/ApplicationHelper.cfm.
					Note: If you wish to use an absolute template path (for example, template="/mypath/index.cfm") with include, you must create a mapping for the path using the ColdFusion Administrator. Or, you can use per-application settings to specify mappings specific to this application by specifying a mappings struct to THIS.mappings in Application.cfc. <br> Using relative paths (for example, template="index.cfm" or template="../index.cfm") does not require the creation of any special mappings. It is therefore recommended  that you use relative paths with include whenever possible.. | DSL: , Path: handlers.Main,
b
What does it do without the period
j
Thanks for the suggestion, Brad. It looks like it just prints the same error message, minus the period:
Copy code
Error @Fri, 21 Apr 2023 16:58:01 GMT: Builder.BuildCFCDependencyException | Error building: handlers.Main -> Could not find the included template ///includes/helpers/ApplicationHelper.cfm.
					Note: If you wish to use an absolute template path (for example, template="/mypath/index.cfm") with include, you must create a mapping for the path using the ColdFusion Administrator. Or, you can use per-application settings to specify mappings specific to this application by specifying a mappings struct to THIS.mappings in Application.cfc. <br> Using relative paths (for example, template="index.cfm" or template="../index.cfm") does not require the creation of any special mappings. It is therefore recommended  that you use relative paths with include whenever possible.. | DSL: , Path: handlers.Main,
So I ended up making the
applicationHelper
key in the
coldbox.cfc
coldbox struct equal to an empty string, as we aren't actually using anything defined in this file in the app. This made the error stop popping up. However, now we're seeing an error that says our two leading slashes are being prepended to references to our modules. This surely is odd.
Copy code
Error @Fri, 21 Apr 2023 19:17:32 GMT: Builder.BuildCFCDependencyException | Error building: handlers.Main -> Could not find the included template ///modules/BCrypt/helpers/mixins.cfm.
					Note: If you wish to use an absolute template path (for example, template="/mypath/index.cfm") with include, you must create a mapping for the path using the ColdFusion Administrator. Or, you can use per-application settings to specify mappings specific to this application by specifying a mappings struct to THIS.mappings in Application.cfc. <br> Using relative paths (for example, template="index.cfm" or template="../index.cfm") does not require the creation of any special mappings. It is therefore recommended  that you use relative paths with include whenever possible.. | DSL: , Path: handlers.Main,
b
I would assume your app mapping is screwed up
But you really haven't shared enough information about your app to know
Is the ColdBox app in a sub folder off the web root?
What does your Application.cfc bootstrap look like?
Here is the logic from the ColdBox core-- you can see there are a few ways ColdBox tries to resolve the file. https://github.com/ColdBox/coldbox-platform/blob/master/system/FrameworkSupertype.cfc#L688-L714
Your double slashes are most likely coming from logic like this (with an empty app mapping)
Copy code
var UDFRelativePath = expandPath( "/" & appMapping & "/" & udflibrary );
j
As for figuring out if the app is in a sub folder off the web root, I'll be messaging my coworker about that. I'm pretty sure the ColdBox app is located directly in the webroot (no subfolder), but we can verify.
b
Well, that's a BIG difference
A whole bunch of settings which makes assumptions about what the
/
mapping points to can be wrong when you move to a sub folder, especally if you're prod server is not working the same as your dev server.
But, all you need to do is step through the logic I linked to above. Figure out which of those if statements applies to you and why it's not getting hit
šŸ™Œ 1
fileExists()
must have returned true for ONE of those checks
j
So I can say with pretty high confidence that the web root is the directory of the ColdBox app. It's the first time I've pushed a server to production and worked with stuff like IIS, so I don't know what I don't know.
I think you're right that the double slashes are probably coming from an empty
AppMapping
variable that gets concatenated there. I need to figure out how to set that now.
b
If ColdBox is in the web root, then you don't need to set an app mapping. An empty string is corret.
j
I found this in my application.cfc. Is this what you mean by bootstrap?
Copy code
// COLDBOX STATIC PROPERTY, DO NOT CHANGE UNLESS THIS IS NOT THE ROOT OF YOUR COLDBOX APP
	COLDBOX_APP_ROOT_PATH = getDirectoryFromPath( getCurrentTemplatePath() );
	// The web server mapping to this application. Used for remote purposes or static purposes
	COLDBOX_APP_MAPPING   = "";
	// COLDBOX PROPERTIES
	COLDBOX_CONFIG_FILE   = "";
	// COLDBOX APPLICATION KEY OVERRIDE
	COLDBOX_APP_KEY       = "";

// application start
	public boolean function onApplicationStart() {
		try
		{
			application.cbBootstrap = new coldbox.system.Bootstrap(
				COLDBOX_CONFIG_FILE,
				COLDBOX_APP_ROOT_PATH,
				COLDBOX_APP_KEY,
				COLDBOX_APP_MAPPING
			);
			application.cbBootstrap.loadColdbox();

			return true;
		}
		catch(any e)
		{
			writeDump(e);
			// fileAppend( "#appPath#/error.log", "Error: #e.type & "---" & e.message & "---" & e.detail#" );
		}
	}
b
Yes.
Copy code
COLDBOX_APP_MAPPING   = "";
your app mapping is not being set to anything special.
j
@bdw429s I stepped through the logic of the framework supertype's
includeUDF()
function as you suggested. I edited the FrameworkSupertype.cfc to do some debugging. For
includeUDF()
, I added
fileAppend()
calls which tell me what
fileExist()
condition was met in the inner closure function and ultimately what the returned
targetLocation
variable was:
Copy code
any function includeUDF( required udflibrary ) cbMethod{
		// Init the mixin location and caches reference
		var defaultCache     = getCache( "default" );
		var mixinLocationKey = hash( variables.controller.getAppHash() & arguments.udfLibrary );

		var targetLocation = defaultCache.getOrSet(
			// Key
			"includeUDFLocation-#mixinLocationKey#",
			// Producer
			function(){
				var appMapping      = variables.controller.getSetting( "AppMapping" );
				var UDFFullPath     = expandPath( udflibrary );
				var UDFRelativePath = expandPath( "/" & appMapping & "/" & udflibrary );

				// Relative Checks First
				if ( fileExists( UDFRelativePath ) ) {
					targetLocation = "/" & appMapping & "/" & udflibrary;
					fileAppend("my\absolute\path\webroot\logs\application-cfc-errors.log", "1");
				}
				// checks if no .cfc or .cfm where sent
				else if ( fileExists( UDFRelativePath & ".cfc" ) ) {
					targetLocation = "/" & appMapping & "/" & udflibrary & ".cfc";
					fileAppend("my\absolute\path\webroot\logs\application-cfc-errors.log", "2");
				} else if ( fileExists( UDFRelativePath & ".cfm" ) ) {
					targetLocation = "/" & appMapping & "/" & udflibrary & ".cfm";
					fileAppend("my\absolute\path\webroot\logs\application-cfc-errors.log", "3");
				} else if ( fileExists( UDFFullPath ) ) {
					targetLocation = "#udflibrary#";
					fileAppend("my\absolute\path\webroot\logs\application-cfc-errors.log", "4");
				} else if ( fileExists( UDFFullPath & ".cfc" ) ) {
					targetLocation = "#udflibrary#.cfc";
					fileAppend("my\absolute\path\webroot\logs\application-cfc-errors.log", "5");
				} else if ( fileExists( UDFFullPath & ".cfm" ) ) {
					targetLocation = "#udflibrary#.cfm";
					fileAppend("my\absolute\path\webroot\logs\application-cfc-errors.log", "6");
				} else {
					throw(
						message = "Error loading UDF library: #udflibrary#",
						detail  = "The UDF library was not found.  Please make sure you verify the file location.",
						type    = "UDFLibraryNotFoundException"
					);
				}
				
				fileAppend("my\absolute\path\webroot\logs\application-cfc-errors.log", "The following was the targetLocation intended to include: " & targetLocation);
				
				return targetLocation;
			},
			// Timeout: 1 week
			10080
		);

		// Include the UDF
		include targetLocation;

		return this;
	}
On starting the server, these messages were logged to the file:
Copy code
1
The following was the targetLocation intended to include: ///modules/BCrypt/helpers/mixins.cfm
1
The following was the targetLocation intended to include: ///modules/cbauth/helpers/Mixins.cfm
1
The following was the targetLocation intended to include: ///modules/cbmailservices/helpers/mixins.cfm
1
The following was the targetLocation intended to include: ///modules/cbmessagebox/helpers/mixins.cfm
1
The following was the targetLocation intended to include: ///modules/cbsecurity/helpers/mixins.cfm
1
The following was the targetLocation intended to include: ///modules/cbsecurity/modules/cbcsrf/helpers/Mixins.cfm
1
The following was the targetLocation intended to include: ///modules/cbvalidation/modules/cbi18n/helpers/Mixins.cfm
1
The following was the targetLocation intended to include: ///modules/cbvalidation/helpers/Mixins.cfm
No errors here. Things look normal. Now, when the session ends, we get the following logged message that we've been getting for a while. Interestingly though, none of the
fileAppend()
calls appear to have been hit:
Copy code
Error @Mon, 24 Apr 2023 13:02:26 GMT: Builder.BuildCFCDependencyException | Error building: handlers.Main -> Could not find the included template ///modules/BCrypt/helpers/mixins.cfm.
					Note: If you wish to use an absolute template path (for example, template="/mypath/index.cfm") with include, you must create a mapping for the path using the ColdFusion Administrator. Or, you can use per-application settings to specify mappings specific to this application by specifying a mappings struct to THIS.mappings in Application.cfc. <br> Using relative paths (for example, template="index.cfm" or template="../index.cfm") does not require the creation of any special mappings. It is therefore recommended  that you use relative paths with include whenever possible.. | DSL: , Path: handlers.Main,
I find this strange because we have clearly defined these function calls before the line where the error is thrown. Do you have any insight on what could be occurring here? I know you mentioned the application mapping being messed up earlier.
b
Interestingly though, none of the
fileAppend()
calls appear to have been hit:
Presumably because the lookups are cached. If you wanted them to happen every time, you'd need to refactor out the caching.
I find this strange because we have clearly defined these function calls before the line where the error is thrown.
No, you put your logging inside of the cache provider UDF, and the error is actually coming form the cfinclude down below. So the cached value was simply retrieved and then attempted to be cfincluded.
I had totally missed that this is on an onSessionEnd method-- I assume the issue is that whatever mappings Lucee has are missing or different from inside of the onsession end
I'm not really sure you're debugging is telling us exactly why the file isn't found
I'm also not quite clear if the extra slashes are actually an issue or not. CF tends to canonicalize paths and remove extra slashes in many cases, so that may or may not be an issue.
I guess, you need to back up a bit and figure out which of these two scenarios is happening. • is the logic to find the file path wrong and returning the wrong path • or is the path totally fine and the cfinclude is simply not finding the file for some reason
Because the path forward for debugging depends on what exactly you're debugging, lol
I'd be curious in seeing what
Copy code
expandPath( '///modules/cbvalidation/helpers/Mixins.cfm' )
returns at the point that it's erroring. Does it return a valid file path that exists? Does the behavior change if you remove the extra slashes?
j
Thanks for the reply, Brad!
Presumably because the lookups are cached. If you wanted them to happen every time, you'd need to refactor out the caching.
Thanks. I don't know much about the caching here, so I probably want to change how I'm logging debug messages here. I don't know what I don't know šŸ™‚
I had totally missed that this is on an onSessionEnd method-- I assume the issue is that whatever mappings Lucee has are missing or different from inside of the onsession end
Yes, this error is triggered from the onSessionEnd method that lives in
Application.cfc
. That sounds very likely, considering that when the app starts, all of the dependencies are injected correctly. Also it should be noted that we are using Adobe Coldfusion 2021.
I guess, you need to back up a bit and figure out which of these two scenarios is happening.
• is the logic to find the file path wrong and returning the wrong path
• or is the path totally fine and the cfinclude is simply not finding the file for some reason
This sounds like the way to go.
I'd be curious in seeing what
Copy code
expandPath( '///modules/cbvalidation/helpers/Mixins.cfm' )
returns at the point that it's erroring. Does it return a valid file path that exists? Does the behavior change if you remove the extra slashes?
I will go and test this out right now. I appreciate your time Brad. We've credited you and some of the other Ortus guys in the new app we've made šŸ™‚
@bdw429s I think we may have found the culprit: When we log
expandPath( '///modules/cbvalidation/helpers/Mixins.cfm' )
during the resolving of the OnSessionEnd() method, this is the directory that gets printed:
C:\ColdFusion2021\cfusion\wwwroot\modules\cbvalidation\helpers\Mixins.cfm
This path is incorrect. Now, we need to know how to change this, or why this is even the case in the first place.
b
Does removing the extra slashes change anything
It would appear this is likely an Adobe bug where CF mappings are lost in session end handlers, which the more I think of it, the more it sounds like something @lmajano has complained about in the past as a known issue
And if it is a CF bug, then basically you won't be able to use the coldbox session end handling
You can tell what CF thinks the web root is by looking at
expandpath( '/' )
j
Does removing the extra slashes change anything
It looks like removing the extra slashes produces a path with the correct absolute path to
modules/cbvalidation/helpers/Mixins.cfm
right before the error is thrown!
And logging
expandpath( '/' )
during the resolution of onSessionEnd shows:
C:\ColdFusion2021\cfusion\wwwroot\
, which is an incorrect path.
If this is an adobe error, that makes me feel a little better
b
Hmm, that doesn't make any sense
You're saying that
Copy code
expandPath( '/' )
returns
Copy code
C:/one/path/
but
Copy code
expandPath( '/foo' )
returns
Copy code
C:/another/path/foo
?
Unless you have some special CF mapping for
/modules
somewhere, the root
/
mapping should be the same in all expansions
j
Sorry, I need to be more clear. Right before the error throws during onSessionEnd(),
Copy code
expandPath( '/' ) == C:\ColdFusion2021\cfusion\wwwroot\

expandPath( '/modules/cbvalidation/helpers/Mixins.cfm' ) == C:\ColdFusion2021\cfusion\wwwroot\modules\cbvalidation\helpers\Mixins.cfm

expandPath( 'modules/cbvalidation/helpers/Mixins.cfm' ) == the\correct\absolute\path\webroot\modules\cbvalidation\helpers\Mixins.cfm
We do not have a special mapping for modules for this app.
It would seem to be a hacky solution, but could I modify the function to slice off the leading forward slash? I understand that might create problems elsewhere.
b
Yeah, the last one is just working prolly because CF is making the path relative to the file
But this is totally CF being wrong IMO
The mappings should know the web root
I couldn't find a ticket for this in their ticket tracker, but this totally sounds familiar as an issue we've hit before.
j
Okay, thanks for guiding me through this error Brad. I'll see if I can notify adobe of this error if there's not already a ticket for it šŸ™‚
I'll let my coworker know about the cause of this.
Here is the bug that has been reported: https://tracker.adobe.com/#/view/CF-4217744
šŸ‘ 1
b
@Jeff Stevens Generally speaking, don't bother putting links to Slack in the ticket tracker. In addition to only being visible to members of the Slack team, they will go dead in a few weeks anyway due to the Slack history limit. Just put all the relevant details in the ticket so they are there
šŸ™Œ 1
j
Got it! Thank you