I’m sure that pretty much every RedDot CMS Web Solutions Management Server developer would have come up against some pre-executed ASP in their templates that has failed. The ensuing frustration at having no built-in method of debugging or even just getting some sort of meaningful error message out of the CMS WSMS is one of the most discussed annoyances of the product. Sure, there’s the Pre-Execute Debugger plug-in but to use that, changes must be made to the RDServer.ini file. Those changes can render a project unusable or can even crash the RedDot CMS Web Solutions Management Server …err… server (I’ve experienced both scenarios numerous times). The latter of course can be fixed by a reboot but if this is a busy production system, that’s just not practical.
Surely, there must be some way of getting those errors out of the system and back to the developer?
I don’t know if I’m the first person to think of this but I haven’t seen it discussed before so hopefully this is useful information.
Pre-executed ASP is rendered by CMS WSMS before being passed to IIS to run. The resulting code is passed back to CMS WSMS for inclusion in the page. Although you don’t see it, if the ASP fails, a 500 error is generated by IIS. Unfortunately, this information about the 500 error is lost as data is passed between CMS WSMS and IIS and back again.
Under IIS, it’s possible to set a custom error page for each type of error that occurs on the web server. This is traditionally used to provide end-users with a meaningful 404 page on published web sites. We can leverage this functionality to set a custom error page for a 500 error on the CMS WSMS server. In addition to this, the folks at Microsoft have seen their way clear to also provide an Error object that is only available from a 500 error and returns a bunch of useful information about the error. Thus, we can capture the error information and log it to a file.
The first thing we need to do is create some folders.
Next we need to set the RDExecute and PreExecute settings.
At this point, check that your pre-execution is still working in your project.
Now to create the custom error handler.
<% ' Create the error object. Dim objASPError Set objASPError = Server.GetLastError ' Write the error information to a file (formatting of the second argument is for readability only). WriteToFile "C:\Program Files\RedDot\CMS\ASP\PreExecute\logs\PreExecuteErrors_" & Year(Now) & Month(Now) & Day(Now) & ".log", " Date/Time: " & Now() & vbCrLf & " ASP Code: " & objASPError.ASPCode & vbCrLf & "ASP Description: " & objASPError.Description & vbCrLf & " Category: " & objASPError.Category & vbCrLf & " Column: " & objASPError.Column & vbCrLf & " Description: " & objASPError.Description & vbCrLf & " File: " & objASPError.File & vbCrLf & " Line: " & objASPError.Line & vbCrLf & " Number: " & objASPError.Number & vbCrLf & " Source: " & objASPError.Source & vbCrLf & "############################################################" & vbCrLf, True Function WriteToFile(FileName, Contents, Append) On Error Resume Next If Append = True Then iMode = 8 Else iMode = 2 End If Dim oFs, oTextFile Set oFs = Server.CreateObject("Scripting.FileSystemObject") Set oTextFile = oFs.OpenTextFile(FileName, iMode, True) oTextFile.Write Contents oTextFile.Close Set oTextFile = Nothing Set oFS = Nothing End Function %>
Lastly, we need to configure IIS.
To test it’s pretty simple. Assuming your pre-execution was working earlier, you should be able to add some broken ASP code to your template (e.g. <!IoRangePreExecute><%= functionThatDoesNotExist() %><!/IoRangePreExecute>) and preview the page. You should get the standard (read useless) CMS WSMS error page but you should also get a log file created in your CMS/ASP/PreExecute/logs folder with detailed information about the ASP error that has occurred.
If you’re running a clustered CMS WSMS, you may want to be careful with this procedure. When I tried changing the pre-execution settings under a clustered CMS WSMS environment, it not only did not work, it also took down the publication of ALL projects. I haven’t investigated this any further at this stage, if and when I do, I’ll post my findings.
The method described above only works for Classic ASP. It would be great if someone would describe the equivalent process for ASP.NET. Any takers?