Can I append a "megadump" to the default ColdFusion error page? - coldfusion

I wish to toggle friendly error messaging in ColdFusion 9. My app.cfm looks like:
<cfset App.EnableDebug = true>
<CFERROR TYPE="VALIDATION" TEMPLATE="/errorhandler.cfm">
<CFERROR TYPE="EXCEPTION" TEMPLATE="/errorhandler.cfm">
<CFERROR TYPE="REQUEST" TEMPLATE="/errorhandler.cfm">
Currently, my errorhandler.cfm looks at App.EnableDebug and either displays a friendly error message or a cfdump of the error variable and then a "megadump" of all defined variables (app, cgi, session, etc). My problem is we prefer the look/layout of the default error page provided by ColdFusion. However, we also like having the "megadump" of all our variables.
Now, I know that if I just comment out the cferror tags then ColdFusion will display it's default error page. Which is pretty handy, except I wish to include a "megadump" of all my variables. Any way to merge my two desires into one reality?

The default error handler is just a CFM file. You can edit it, or replace it with whatever you like.
This file is located in the server instance's WEB-INF/exception folder. The file name is detail.cfm

You prefer the look of the default error page? Do as Sean suggests, or,
throw an error
save the error page from your browser as errorhandler.cfm
insert your cfdump etc

Similar to Sean Coyne's answer, except a little more safe is to make a copy of detail.cfm and place it in your webroot as error.cfm. Then you can use the cferror tag just like you had before and in error.cfm just add your dumps.
Again the detail.cfm page is in {CFWebRoot}/WEB-INF/exception/.

Related

Coldfusion per application mapping randomly fails

In my application.cfc file I have the following code:
this.mappings["/includes"] = "#expandPath('../../priv/inc/')#";
and then on a page I have the following CF include set up:
<cfinclude template="/includes/imageOptimise-thumbnail.cfm">
For the majority of the time when the page is submitted the imageOptimise-thumbnail page runs without any issue but occasionally it will error saying that it can't find the imageOptimise-thumbnail.cfm. If I resubmit the page, chances are it will work but the question is, why is it sometimes not being able to find the page?
I had a look in the CF Admin and I can't see anything in the logs saying that there was an error but it is clearly showing a Coldfusion 'template not found' error message when it fails.
Anyone got any ideas?
I think your issues stem from the fact that the path used for the mapping is relative.
According to advice in ColdFusion Mappings and Relative Paths,
the moral of the story is to NEVER use expandPath() to create a
mapping that’s relative to the webroot.
Try to make the webroot static as the blog suggests
<cfset this.mappings["/myapplication"] =getDirectoryFromPath(getCurrentTemplatePath())
and navigate to /priv/inc/ from the webroot

Do custom tags in application.cfc ignore this.customTagPaths?

Within my root application.cfc I define this.customTagPaths. This is verified to work on all pages, including those in subfolders. Within one subfolder I have an application.cfc that extends this root application.cfc. Pages within this folder still use the correct custom tags so we know that this is working correctly.
However, when trying to use a custom tag within the [subfolder]/application.cfc file itself I believe it is pulling from a different custom tag path. I added some debug information into the custom tag and it outputs when the custom tag is called from a normal page, but does not output when called from the application.cfc. I do not have access to the server to put debugging information in the other custom tag paths to be sure.
Does code in the application.cfc ignore this.customTagPaths and, if so, how do I use the specific tag I need? This custom tag sets a variable in the caller scope, so it cannot be called with a simple cfInclude.
Edit
I will attempt to address some of the questions in the comments here.
The custom tag in question has been simplified down to this code:
<cfset Caller.groupList = "">
<cfquery name="getGroups">
SELECT id, name
FROM groups
WHERE id = 1
</cfquery>
<cfoutput query="getGroups">
<cfset Caller.groupList = #ListAppend(Caller.groupList, name)#>
</cfoutput>
<cfoutput>Caller.groupList: #Caller.groupList#<br></cfoutput>
The Application.cfc is using this code:
<cfcomponent extends="RootApplication">
............
<cf_groupList>
<cfoutput>request.groupList: #request.groupList#<br><br></cfoutput>
</cfcomponent>
When cf_groupList is called directly from a cfm it writes "Call.groupList: xxxx" out to the page and shows the correct values from the dev database. However, when the Application.cfc runs the custom tag "Call.groupList: xxxx" never appears, but "request.groupList: xxxx" does, and in the latter case it shows the list that we would expect from the live database. Both the live and dev sites are currently on the same server, which we are in the process of changing, but for now I have no debugging information.
The reason I am calling a custom tag from Application.cfc is because this tag is used many other places. Simply copying and pasting the code into Application.cfc would solve the problem, but then we have an issue of duplicated code that we need to remember to update in two places in the future. Using the custom tag in the application.cfc instead of duplicating code seemed like the correct approach.
Mark, you are correct. When placed in the parent Application.cfc the custom tag works correctly. In the child it does not.

How do you acquire the rewritten CFWheels URL of an given page?

CFWheels has the URLFor() function for getting the internal URL based on supplied arguments. Is there a way to get the internal URL without supplying any arguments?
For example:
Given a user navigates to "http://somedomain.com" or "http://somedomain.com/about/" or "http://somedomain.com/contact/" is there a method like ReWrittenURL() that returns something like "/" or "/about/" or "/contact/"?
Using URLFor() with no arguments returns "/home/index" or "/about/index" or "/contact/index".
CGI.SCRIPT_NAME returns "/rewrite.cfm"
Obviously with Javascript using document.location.href I can get what I'm after.
Does CGI.path_info have the value you're looking for?
edit
At first, I deleted this post, being utterly confounded. Now I've done a little test - I downloaded the latest wheels core files (1.1.6), extracted to an IIS 7.5 (with URL Rewrite module installed) + CF9 webserver, and edited the "web.config" file in the core root, setting "enabled='true'" for the rewrite rule. Also, since I was running this example from a subfolder, I changed the path from "/rewrite.cfm" to just "rewrite.cfm". This got me to the point where I was able to successfully requests urls like this:
http://server/wheelstest/wheels/wheels
From here, I edited the layout.cfm under views/wheels, adding:
<cfdump var="#cgi#">
When I then request the above URL (/wheelstest/wheels/wheels), I see the dump for the cgi scope. Under path_info, this is the value: /wheels/wheels.
Next, I added a blank "index.cfm" file under views/wheels.
When I request /wheelstest/wheels, I get this for path_info: "/wheels".
When I request /wheelstest/wheels/, I get this for path_info: "/wheels/".
When I request /wheelstest/wheels/index, I get this for path_info: "/wheels/index".
When I request /wheelstest/wheels/index/, I get this for path_info: "/wheels/index/".
So basically - cgi.path_info is doing for me exactly what you describe you want. What is different about your setup than mine, such that it isn't returning that value for you?
there might be a better way to do this... but here I go anyway
every page gets sent the #params#
<cfdump var="#params#">
<cfoutput>#params.action#/#params.controller#/#params.key#</cfoutput>
<cfabort>
try putting that in a controller and see the results
the problem is that if the objects inside the params object don't exist you get an error. So the path that gets generated needs to check if the struct key exists and edit accordingly.
CGI.Path_Info will give you the desired results. I've been trying different options however they all failed and went into the redirect loop. As soon as I switched CGI.path_info it all started well.

What does this URL mean?

http://localhost/students/index.cfm/register?action=studentreg
I did not understand the use of 'register' after index.cfm. Can anyone please help me understand what it could mean? There is a index.cfm file in students folder. Could register be a folder name?
They might be using special commands within their .htaccess files to modify the URL to point to something else.
Things like pointing home.html -> index.php?p=home
ColdFusion will execute index.cfm. It is up to the script to decide what to do with the /register that comes after.
This trick is used to build SEO friendly URL's. For example http://www.ohnuts.com/buy.cfm/bulk-nuts-seeds/almonds/roasted-salted - buy.com uses the /bulk-nuts-seeds/almonds/roasted-salted to determine which page to show.
Whats nice about this is it avoids custom 404 error handlers and URL rewrites. This makes it easier for your application to directly manage the URL's used.
I don't know if it works on all platforms, as I've only used it on IIS.
You want to look into the cgi.PATH_INFO variable, it is populated automatically by CF server when such URL format used.
Better real-life example would look something like this.
I have an URL which I want to make prettier:
http://mybikesite/index.cfm?category=bicycles&manufacturer=cannondale&model=trail-sl-4
I can rewrite it this way:
http://mybikesite/index.cfm/category/bicycles/manufacturer/cannondale/model/trail-sl-4
Our cgi.PATH_INFO value is: /category/bicycles/manufacturer/cannondale/model/trail-sl-4
We can parse it using list functions to get the same data as original URL gives us automatically.
Second part of your URL is plain GET variable, it is pushed into URL scope as usually.
Both formats can be mixed, GET vars may be used for paging or any other secondary stuff.
index.cfm is using either a CFIF IsDefind("register") or a CFIF #cgi.Path_Info# CONTAINS statements to execute a function or perform a logic step.

Can I use any other CF tags to replace CFDUMP?

In the application I designed, I named one of my web pages "error.cfm". I want it to display whenever there is an error from the application. So I put the following code inside "error.cfm":
An uncaught exception just 'happened' :-(
<br><br>
<b><cfoutput>#exception.message#</cfoutput></b><br />
<cfoutput>#exception.detail#</cfoutput><br /><br />
<cfif isdefined('exception.cause')>
<b><cfoutput>#exception.cause.message#</cfoutput></b><br />
<cfoutput>#exception.cause.detail#</cfoutput>
</cfif>
<cfdump var="#exception#">
So after hosting the website, I discovered that this particular page refused to load and instead a '500 Internal Error' was displayed. I then complained to my hosting company and I was sent these details:
Dear Customer,
The actual error message is the following:
Security: The requested template has been denied access to createobject(java).
The following is the internal exception message: access denied (coldfusion.runtime.FunctionPermission createobject(java))
The error occurred in C:\inetpub\vhosts\plat4ad.com\httpdocs\cms\error.cfm: line 10
8 :
9 :
10 :
Unfortunately some tags and functions are disabled on our servers due to security purposes. You can check full list here:
https://support.dailyrazor.com/index.php?_m=knowledgebase&_a=viewarticle&kbarticleid=293&nav=0,29,76
Please let us know if you have any other questions.
Best wishes,
Support-GG
DailyRazor Support Team.
Now checking the lists of the tags they disabled on their servers, CFDUMP was among them:
On the shared ColdFusion servers you will have access to all tags and
functions except for the following:
CF Tags:
CFCOLLECTION
CFCONTENT
CFDUMP
CFEXECUTE
CFLOG
CFOBJECT
CFOBJECTCACHE
CFREGISTRY
CF Functions:
SetProfileString
CreateObject(COM)
CreateObject(CORBA)
CreateObject(JAVA)
Please is there any alternative for CFDUMP? Or does anyone know any ColdFusion hosting company that doesn't have these restrictions? I appreciate any ideas from you.
How about this: http://www.coldfusionjedi.com/index.cfm/2010/10/6/Cant-dump-Try-a-fake-dump
If you get yourself VPS (google:coldfusion VPS) you'll be able to do on that machine whatever you want.
The whole point of not having cdump is security measure. Usually all debugging and dumping raw data is done on development server and on hosted server you run applications, right? Error.cfm is used to hide caught exception details, like path to your files, data about used libraries etc.
There're ways to display data without cfdump. In your case I don't see why you couldn't use plain cfoutput and write exception details as 2 lines of output.
In your place, I'd take source codes of fw/1 or Mura CMS to see how they handle error messages, better to see how more experienced people are doing it then to "waste" time reinventing the wheel.
CFDUMP began life as a custom tag before it was ever included in ColdFusion.
It still appears to be downloadable: http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&extid=1002037
You may need to make changes to it to work (better) in more modern versions of CF, but it should probably do more than 90 per cent of what you need it for.
I will add that if you choose to "dump" details, you can also wrap the dump code in an "if" block that looks at your cgi.REMOTE_ADDR and if it matches your IP address, does the dumpout, otherwise doesn't.
<cfif cgi.REMOTE_ADDR EQ "167.96.177.66">
<!--- execute dump code here --->
</cfif>
Caveats: YMMV, have to have a static IP, have to BE at that IP, etc.