Thursday, 4 December 2008

Fun with Server.GetLastError() in classic ASP on Windows Server 2008

One of our sites, written many moons ago in classic ASP using JScript, uses a bunch of custom error pages to handle 404 errors, scripting errors, and so on.

Our error handling code looks like this:

var error = Server.GetLastError();
var errorMessage = "";
errorMessage += Server.HTMLEncode(error.Category);
if (error.ASPCode) errorMessage += Server.HTMLEncode(", " + error.ASPCode);
var errorNumber = error.number;
errorNumber = ((errorNumber<0?errorNumber+0x100000000:errorNumber).toString(16))
errorMessage += " error 0x" + errorNumber + " (from " + Request.ServerVariables("SCRIPT_NAME").Item + ")\r\n\r\n";
if (error.ASPDescription) errorMessage += "ASPDescription: " + error.ASPDescription + "\r\n";
if (error.Description) errorMessage += "Description: " + error.Description + "\r\n";

// and then we log and useful with errorMessage

On our old server, this worked because the HTTP 500 error page was mapped to a custom URL, /errors/500.asp, which included the code above.

When we migrated our site onto IIS7 recently, this stopped working - the custom page was still executing, but Server.GetLastError() wasn't returning any information about what had gone wrong.

There was a very similar known bug in Vista which was supposedly fixed in SP1, but it looks like the same fix isn't part of Windows 2008 Server yet. There is a workaround, though - if you set the site's default error property (under IIS settings -> Error Pages -> Edit Feature Settings...)to the custom page (see below), IIS will invoke this page whenever an error is not handled by an explicitly configured status-code handler (so your 404, etc. handlers will still work) - but for some reason, handling the error this way means Server.GetLastError() still works properly.



Anonymous said...

That's kind of worrying, though glad you've identified a fix.

I say that because we're hoping to redeploy all our web sites to Server 2008 & IIS 7 over the next few weeks. Including some legacy asp code.

Maybe it won't be as simple as I'd hoped...

Dylan said...

Hi Ed,

Our site does pretty much everything possible with legacy ASP - Windows Script Components, redirects, COM, mapped drives, various redirects and custom error pages. Since migrating to (32-bit) Windows Server 2008, the only problems we've had are with one third-party COM component (which isn't even their fault, it's a security issue with IE), and this one here.

Generally, though, it's worked pretty well, so I wouldn't worry too much.

Richard said...

Thanks for this! Documentation on IIS7 for classic ASP developers is practically non-existent!

If you want to get the same result through web.config you need to add a defaultPath attribute to youe httpErrors line.

(I would post a code example but blogger won't let me! e-mail if you'd like to add to your page!)

Anonymous said...

Thank you VERY much, the trick of settig the default error page was exactly what we needed. Our custom page's Server.GetLastError() was unable to get the error, but now using the default page setting it can.

Anonymous said...

I did same, but still getlasterror() returning no values at all.