April 2003 - Posts

First, turn on custom error reporting in the web.config and name the file you will use as your default handler:

<!-- Web.Config -->
<configuration>
   <system.web>
     <compilation debug="true"/>
     <customErrors mode="On" defaultRedirect="MyErrorHandler.aspx"/>
   </system.web>
</configuration>

At its simplest, that's all there is to it. Apologize to the user and provide some links back to what they were doing before the error. But what were they doing? What is the error? You might be disappointed that variations on the following don't work in MyErrorHandler.aspx:

<%@ Page Language="C#" %>
<script runat="server">

private void Page_Load( object src, EventArgs e ) {
   Exception objError = Server.GetLastError();
   lblMessage.Text=objError.Message;
   lblSource.Text=objError.Source;
   Server.ClearError();
}

</script>
<html><head><title>Server Error</title></head>
<body><form runat="server">
   <p><asp:label id="lblMessage" runat="server" /></p>
   <p><asp:label id="lblSource" runat="server" /></p>
</form></body></html>

The error is past tense by the time you hit the handler page. How do you find it? Keep reading.

The simplest thing to do is to catch and store the Exception inside the Application bag right in your global.asax (or a global.asax.cs codebehind):

<%@ Import Namespace="System.IO" %>
<script language="C#" runat="server">
 
protected void Application_Error( object src, EventArgs e ) {
   Exception objError = Server.GetLastError();
   HttpContext.Current.Application.Add("lastException",objError);
   Server.ClearError();
}
 
</script>

And then retrieve and the display the Exception object's properties (Exception.Message, Exception.Source, Exception.StackTrace, or Exception.TargetSite.Name) inside MyErrorHandler.aspx (as named in your web.config).

private void Page_Load( object src, EventArgs e ) {
   Dim objError As System.Exception = HttpContext.Current.Application.Get("lastException") ;
   lblMessage.Text=objError.GetBaseException.Message;
   lblStackTrace.Text=objError.GetBaseException.StackTrace;
}
...

Further reading on error handling: http://www.c-sharpcenter.com/asp.net/customerrors.htm

Advanced User Note: On a busy site, use of the Application object impedes scalability. Application objects are a late-bound kludge to help migrate from Classic ASP to .NET. Ideally you should grab the Exception properties into static fields in some sort of Global class which could then be accessed by the custom error page.

Further reading on the Application object: http://www.eggheadcafe.com/articles/20030211.asp

Caveat: Recognize that on a high traffic site which generates nearly simultaneous errors, since this method records the last error in the Application and not the last error in the Session, by the time the Custom Error page is displayed a user could conceivably get someone else's error message. Though not a common problem on most sites, it could potentially confuse whoever is debugging the problem.

A solution to this would be to write the error into a log right when it is raised and debug with the log. The article on error handling above covers writing to the Event Log.

Enjoy!

[Updated 2003-09-18: Corrected the sample code which didn't properly grab the error from the Application object, doh eh!]

Posted by erobillard | 14 comment(s)
Filed under: ,
Don Box:
Old stuff gets older.
 
New stuff replaces it.
 
Even XML will eventually be overtaken by something else.
 
When this stops happening, I'm changing professions.
 
Well sometimes things just work. Then, unless "fashion" matters, they don't change. Either the thing reaches a level of simplicity that can't be improved upon (seen any new designs for coat hangers lately?) or they become so entrenched that only a major industry shift will have any effect on their dominance.
 
An example of the latter would be TCP/IP. It just works. We got it right and now the level of focus is on secondary things -- appliances to interpret and route it, encryption, and so on. Even as addressing migrates to IPv6, the mechanics don't change all that much, just the size of the address space. It amounts to a new feature, conceptually closer to making int32 available in addition to int16, not so much like the jump from IPX/SPX to TCP/IP, or from CISC to RISC where designers need to change their language entirely.
 
XML is one of those things that is is general enough it probably won't change all that much, though our tools for manipulating and expressing it will. It is inherently flexible and already proven useful whatever the culture, character set, industry, or methodology it is applied to. It just works.
 
The boundary of focus was once the PC, then the network, then the WAN, then the Internet. Next it's about connecting the Internet to mobile devices and everyday objects.
At the same time, business has moved from connecting PCs to connecting the Enterprise to connecting companies with XML and next will be about communication among industries.
 
When the boundaries stop moving, then I'll change professions. Don, in the meantime, save a seat by the pool.
 
Further reading:
Posted by erobillard | with no comments
Filed under: ,

Through all this buzz on Chris Brumme's new blog, I haven't seen much mention on Brad Abrams' relatively-new blog at the same site. It's also damn good, and also shares FAQs culled from internal MS feeds. Check it out.

For A Brief History of Time, Stephen Hawking's ratio of books-bought to books-actually-read was (excuse the reference) astronomical. It was a great book, but its position on most bookshelves was as a vanity item rather than a practical, day-to-day reference.

That said, let's have a show of hands: who else has Ingo on their blogroll? (hands go up) Wow, that's quite a few. Who just added Chris Brumme? (a few more go up) How many of you have actually applied anything they've ever written? (a gentle breeze runs through the theatre as many hands whoosh to a position of rest)

Well, keep reading them, and any others like'em. Especially the ones where you don't always know what's going on. As Mario Andretti said, "If you feel like you're in control, you're not going fast enough." Here's to looking forward.

Posted by erobillard | 2 comment(s)
Filed under: ,

Scott's recent rant on signal-to-noise in the dotnetweblog community should get people thinking about self-control. Unfortunately, the feedback he received puts the burden on his end (the distribution layer) to create topical aggregate feeds and global categories. That should not be where the responsibility ends.

Get your categories organized! I did and this is what I learned:

1) Divide your content into "original" and "everything else." Make a way for people to avoid your "me too" blogs. Allowing people to filter on this alone could kill half the junk bandwidth out there. I set up three categories for the purpose:

Original Content

My Two Cents (Derivative Content): Used when I've added my two cents to other threads. A mix of original content and duplicated, external content.

Me Too (Duplicated Content): Links or referrals where I add less than two cents. Long-term, no one cares about the day I set up a blogshares account.

I had the urge to put all my Lazy Programming posts into Original Content, but anyone can get at the complete set through the Lazy Programming Category. Ah, the trials of applying normalization to real-life. The point here is to have abstract topics (like "original" and "derivative") to cross-reference against your physical topics (like "C#" or "movie reviews"). You might prefer different divisions like "internal / external," "timeless / limited shelf-life," or "constructive / rants."

2) Don't create topical categories until you use them  twice. Garbage-collect and adjust your categories once in a while.  It helps to click all your category links to see if they really provide useful groupings. When I started this blog I expected to write more music and XML, two favourite subjects. When I clicked them today they didn't provide solid enough groups to justify keeping either.

3) Avoid uncommon names when a common name will do. I called my links category "Out There" because it seemed both logical and remotely original to me. But it's a poor choice and creates a barrier to every user accustomed to the word  "Links." Links might be an over-used term, but I'm kidding myself if I think a "creative" term will be clicked more. The goal is to produce content, ego kills. If you want to start a cult, learn the lesson that the best cults started with content, not ego.

How do you avoid wasting your readers' time? I understand you're busy preparing a new blog for anyone who doesn't already know about InfoPath, but please, give it some thought.

With the updated Amazon Link Generator you can generate links to Amazon.com complete with your personal AssociateID easier than ever. Anyone who's used it knows that Amazon's own tool for the purpose is kinda klunky, and it's a hassle hacking together your own URLs.

Now, just type your title (or author, or subject) in the Search box, and the tool retrieves Amazon's search results. From there you can click on any result to have the generator create all the links you need for easy cut-and-pasting into your document. If you have an AssociateID, it will be remembered from session to session.

Or, if you're surfing Amazon and you see a book you want to include in a web page, just grab its Url and paste it into the generator. The ASIN will be automatically extracted and links generated in a variety of popular formats.

Behind the curtain, the tool uses Amazon's XML interface to retrieve search results, which it binds to a datagrid which repackages the output with templates. The ASIN extractor uses a simple regular expression to pull out the 10-digit ASIN. Cookies store your personal AssociateID between sessions, and an option is included to delete all cookies set by the tool.

On the design side, table and cell widths and other formatting elements are re-used throughout for consistency. Buttons contain enough descriptive text to be big and easy to hit. Links that open new windows say so. Links and acronym tags and provided for elements that may not be self-explanatory.

Enjoy!

Posted by erobillard | with no comments

When writing blogs it is handy to include links to related books at Amazon.com. It points the reader to good resources, and if you have an AssociateID you can even make a few bucks when your click-throughs result in sales at Amazon.

The hassle is hacking together the URLs with both the custom ASIN and your AssociateID.

Until now. Presenting:

Eli's Amazon Link Generator

Paste either the book's 10-digit ASIN, or paste the whole Amazon link into the generator, and it will parse out the 10-digit ASIN for you. Write in your AssociateID (optional) and it will remember you from visit to visit, just bookmark the page for the next time you're blogging.

Want a new feature or a link in a format you don't see? Just ask!

Sample output:

Results

Book Link
http://www.amazon.com/exec/obidos/ASIN/0201485672/wwwerobillarc-20

Small Image Location
http://images.amazon.com/images/P/0201485672.01.THUMBZZZ.jpg

Medium Image Location
http://images.amazon.com/images/P/0201485672.01.MZZZZZZZ.jpg

Medium Image Link (and HTML Source)

<A href="http://www.amazon.com/exec/obidos/ASIN/0201485672/wwwerobillarc-20"><IMG src="http://images.amazon.com/images/P/0201485672.01.MZZZZZZZ.jpg"></A>

Scott's been tracking the open source vs. commercial debate and I've been meaning to weigh in.

Several governments are requiring that their I.T. folks stick to open source platforms and apps. I can't remember the last time a government specified "cars in the motorpool should not require a licenced mechanic to repair," or "only get photocopiers the secretaries can repair," or "only hire architects who let us fiddle with their drawings." But now you could also add "we wanna see the source so we can use undocumented features and complain when they break."

It's a giant crock. And not of tasty chili.

If something else is going on, what could it be? What motivates this call for open code? Well, in my years with government I knew one constant: when there were lay-offs, the I.T. department grew. I.T. even had a separate union to kill the risk of everyone walking the lines at once. Offering a golden handshake to dump the deadweight? Cool. That meant we'd get another full-time developer and maybe a network upgrade. As Nantucket Clipper is my witness, this was at least an annual event.

Now the call for leaner staffing is louder than ever, so what's an I.T. group to do? Everyone knows it takes more skill to maintain Linux than it does Windows. Windows is the long-term ROI payoff, Linux is a free download today. No government department I ever heard of budgets for a 3 to 5 year span. And Linux has geek cachet, if it doesn't get you re-hired at least you'll speak the jargon. You don't look like a dummy, if you were a government I.T. guy what would you pick?

Commit to Microsoft and any grad with a breaking voice to match his complexion is an MCS-something away from doing your job cheaper. Windows is cookie-cutter, Linux lets you build all the nooks and crannies you please. Make a case in any given year that Linux will save tens or hundreds of thousands to deploy and if you place those nooks right, your job (and post-job consulting path) is safe for the lifespan of the platform. If you're the sort of person who asks, "Who would do that?" then you haven't lived.

I had some great people around during my first internships. Vaughn wrote robust code and knew how to test. Murray knew databases and taught me to write code that anyone could maintain. But as the orange glow of a Compaq 286 luggable was my witness, 75% of the pre-existing apps I was assigned to work on were easier to rewrite than update. It was a culture of bad code. Murray, Vaughn, and every other competent architect, developer or network administrator inevitably moved on.

25% of that bad code could be blamed on a lack of training. Training's priority on the totem pole came just below conversion of a washroom to a "separately ventilated smoking room." The real problem was the other 50%. This code was difficult to trace, hard to maintain, and often produced by shops who would only fix bugs if you bought a "service agreement."

You can draw a Microsoft/commerical comparison there, but it would be weak. This was proprietary stuff, there was zero market pressure (or motivation) for the vendor to otherwise lift a finger, an argument which sticks to open source stronger than to commercial apps. The endgame is this: if the original programmers are intent on protecting their gravy train, you can not fix these apps in-house if you tried. Opening the source would not help. Keeping the free-market free of artifical rules is the only path to superior software.

I was once called in because after six months no one could figure out how to add a single new total to a critical report. The code was disgusting. The original authors wanted as much to add that value as they charged to write the app. It took me roughly a week to re-write the whole damn thing for a fraction of the price, with the goal that any grad with a spare coffee break could now trace an obscure bug or add features to it.

Will opening the source produce better behaviour from vendors? I don't see a reason for it. Will it help or hinder government I.T. job security? Call the bookie, I'll take a marker for four-score finskis on "help." Is this true of every government I.T. department? Not at all, there are loads of top-notch people who could code the stuffing out of the best corporate guys. Are they common? Sure, at least as common as those photocopiers that never require service calls.

Posted by erobillard | with no comments
Filed under:
More Posts