Well, my Exception Dialog is completed.
In essence, it's purpose is to allows you to show exceptions to the user in a less intimidating way, while preserving the technical details that you may need.
How to use:
Ayende.Utilities.Error.ExceptionHandler.InitExceptionHandling(false,
"[email protected]", "[email protected]", "Debug info: WinXP, 128MB, SP1,
.NET 1.1.?, etc", "your.smtp-server.com", "Exception details");
Ayende.Utilities.Error.ExceptionHandler.HandleException(ex);
(There is some documentation in the file that explains everything, so I won't go over the boring details here.)
The above line of code will handle all unhandled exceptions, it will show a nice dialog to the user, with an option to send you the exception's info.
If
for some reason it's impossible to send mail (not connected to network,
for example), the user is prompt to save to file, so he can sent it to
you by some other means (print & fax it, perhaps?)
As for normal use, just do this:
try
{
//... some code that might throw exception
}
catch(MyException ex)
{
Ayende.Utilities.Error.ExceptionHandler.HandleException(ex);
}
Here is how it looks:
Simple dialog && Advance dialog
How do you choose which will be shown?
HandleException() checks in the application configuration file for ShowDetailedExceptionDialog, if it equal to "True" (case sensitive, mind you), then the detailed exception dialog is shown, otherwise, the simple exception dialog is shown.
But there is a trick, press Backspace in the simple dialog, and it will show you the detailed dialog. Neat, isn't it :-S
The bits are here (removed link because it's old and very simple thing, and I need the space in the server)
Here it is, guys. My configuration manager.
I really likes this syntax:
string ConStr = ConfigurationSettings.AppSettings["ConnectionString"];
But this is read-only application-wide settings, it doesn't help you if you
need to update the values, or want to use both application wide and user
specific settings.
For this, I designed my own configuration manager, usage is really simple:
string ConStr = Configuration.AppSettings["ConnectionString"];
So far, exactly like you would've done normally, the real power is in the following statements:
if(Configuration.CanSetAppSettings)
Configuration.AppSettings["ConnectionString"] = ConStr;
string Title = Configuration.UserSettings["Title"];
Configuration.UserSettings["HomePage"] = HomePageUri.ToString();
You can set the application settings, and you get user specific settings also
settable.
Considering that as a normal user you might not be able to make machine-wide
changes, you also get the CanSetAppSettings property, that tells you whatever
you are allowed to do so.
The settings are preserved as XML files in the following directories:
Application settings:
%CommonApplicationData%\<you application name\<major version>.<minor
version>\<your application name>.config
User settings:
%ApplicationData%\<you application name\<major version>.<minor
version>\<your application name>.config
You can also get the file names programmatically using the UserFile and the AppFile properties.
You can iterate over the settings using the following syntax:
foreach(string key in Configuration.UserSettings)
Console.WriteLine(Configuration.UserSettings[key]);
There is a tiny optamization for when you set a lot of settings in one go, to avoid saving them one by one, the actual saving is done tenth of second after the last setting, or at application shut-down.
Curently the only limitation is that it can handle strings only (similar to the FCL's ConfigurationSettings). If there will be demand, I will add the ability to serialize objects directly from the Configuration class.
Get it here.
Enjoy.
I'm planning on developing a set of utilities that I would use as building
blocks for other applications. The main reason that I first and foremost a
developer, I get itchy restless unless I code something.
The other reason is that I simply don't have the time to take on a lengthy
project, but small & useful things are just right.
Currently I've a configuration manager that does user & app settings, like
Whidbey has, and an exception UI Dialog which I still need to polish a little
bit.
I'll show the configuration manager after I finish adding some finishing touches. The exception dialog will take some time, because I want to make it into a real working component, and not just some toy.
Well, it's about time that I introduce myself properly, I think.
My real name is Oren Eini, I'm 22 years old. I lives in Israel, in a boring
sleep-only town near Tel-Aviv.
I work at prison. :-D
Today is my 699th day in prison.
That kind of thing simply ruins a person's resume, don't you think?
Anyway, I've in one prison or another for most of my service. It's one of those
things that you don't really think about. You know that they exist, but no one
bother to think about them.
Never mind, that is just a temporary setback, I'm an IT person at heart.
:-)
It's kind of interesting, in a way. I get to lead a different life
when I'm at prison and when I'm at home. My end-of-service date is a sixteen
months from now, and you can't imagine how much I look forward to it. I want to
learn, there is so much to learn —
and so much that I'm interested at — that it's actually a
bit depressing.
I'll get to go to the university at the time where most people finish it. But it
was worth it for the experience. It's kind of hard to explain, but the banal
saying does it best: "The army will make a man out of you."
Well, in my case, it was prison:-D.
But I get to meet a lot of interesting people and get exposed to a lot of
hate things that I would've never seen otherwise. I was in Prison 6 for a
while, which is a prison for soldiers (you know, desertion, discipline,
drugs, etc.), horribly long working hours, but the people are
interesting.
Now I'm in a prison for terrorists, which has normal better working
hours, but more ethical dilemmas. People never think about what is going
on after that terrorist or the other is arrested. Someone has to take care of
them, feeding, health-care, keeping them looked, etc. It's a difficult problem,
because on one hand you are keeping terrorists in prison, and on the other hand
you make sure that they are whole & hearty.
Considering that most of the people I get to work with are a few years younger than me, that problem multiplies, most of them sees the world in black & white, and it's
hard to make sure that their attitude remains professional.
BTW, I just googled for info about my prison, most of the English links contain some pretty derogatory information, not to mention incorrect.
Shortly after I decided to create myself a web site I'd a very annoying problem to solve. The web site look & feel.
I hope that I don't need to tell you how important that a site will have a recognizable and pleasing to the eye look.
You can see that I pick a warm scheme for my site, simply because I like the colors.
I don't like the cold color schemes, the blue on gray or the gray-scale sites may look proffesional, but I think that they lack life.
There are many ways to create a color scheme, I simply choose a warm color (in thiscase FF9933 which translate to this color, and then I started playing, seeing what colors are working along with it. The result, if I say so myself, is quite pleasing to the eye.
But still, I needed one more quality for this to work. I needed a logo, this was terribly important to me, to get the logo exactly right.
So I fire up Photoshop and after a couple of hours whipped a first proto-type:
This is nice, and I was satisfied with it, especially since it seemed to tax my rather limited graphical abilities. I created this logo following the instructions from Pega Web which tells you how to create a logo even if you are one of those who have trouble drawing a straight line with a ruler.
Considerring that my graphical apps were limited to a trail version of Photoshop that I got from a magazine subscription when dinosaurs roamed the earth and some knowledge of MS Paint.
I wasn't satisfied with this, however, and decided that abastract forms wasn't really for me, so I took a deep breath and tried to create something better:
Much better, I thought, now the “Custom Software Design” caught the eye nicely, and the strange shape (E in Windings2) completed the color balance nicely. But I was satisfied for a short while only, because this still has an amature quality to it.
I thought about it for a while, then decided that it the problem was with the abstract watermark (the orange shape in the background). It was too abstract, and was more appropriate for a cooler color scheme. In fact, merely inverting the colors of the images caused a big improvement:
Not perfect, but better than the originals, obviously this approach doesn't work. Now, considering that this is supposed to be about software, I thought that I could simply use a code background instead of a watermark. Here is the result:
This is nice, actually, and I liked it quite a bit, but is still wasn't quite what I was looking for. I wanted a background that would've more general meaning, and not one so specifically tied to the current purpose of the site. After all, the purpose might change, and I wouldn't want to change the logo then, would I?
So I thought about using some sort of a symbol to create the logo, I toyed for a while with the Windings font, but found that lacking for my purposes, then I thought about using an animal's shadow as the watermark. I thought about using some sort of dragon or a wolf, but those are really banal. I spent some time thinking about it until I finally decided to use a Rhino, I just thought about it and I think that it's cool. Beside, I don't know anyone else that uses Rhinos.
So now I found a picture of a rhino and drew it's outline, and then I'd this picture:
Now, this is nice. It took me some trying, much eventually, I'd the following logo:
This is nice, you can see that I made some changes, the red symbol is much prettier this way, my name is really noticeable, and I like the effect of the green initials. Unfortunately, this image doesn't scale down very easily, and doesn't look good in ??x?? which I uses as the logo size for my blog.
Time for another logo, this time, I was very pleased with it, I got rid of the graveyard's font of my name, and had some nice effects on it. I also removed the "Custom Software Design", this is for the future, not for now. I'd create two rhinos, in different color, which contrast quite well on the logo. Between the rhinos there was a lot of dead place, so I put some the symbol there to fill up the space.
The result is .
Still not good enough for me, too pale by much, and the left rhino is orange on orange, which make the whole logo looks sickly. Not a problem, actually :-)
I changed the color of the left rhino to pale green and increased the opacity of both rhinos, so there are less pronounced. I also increased the vitality of the background so it would be more attractive. Instead of the nearly invisible decoration, I've golden threads running throughout the logo. My name has some nicer effects on it, and the box that contain it got some new effects as well.
The result is .
Still not good enough, though. In the middle, those two symbols annoys me, but I can't just get rid of them, that would leave me a hole in my logo. I looked around a bit found a solution, another symbol, this time colored so it goes from blue (right) to green (left) throughout the whole rainbow.
I'm pretty proud of it, .
I think that it's very well done, and I invested quite heavily in it, the process that you saw here took about a month, all in all. But I'm quite satisfied with the result. Naturally, I would like to know if you've suggestions.
[I wrote this several days ago]
The hour
is 03:15 AM, and I’m sitting here satisfied. Another bug eliminated, another
enemy conquered. And this one is a tricky one.
I’ve
created an application that loads Caudill’s
TreeListView as its main UI. Now, my problem was that after I created about
50% of the application, I decided to work on the start-up data load, and then
the application started to get nasty.
An
IndexOutOfBoundException charged out of nowhere, directly into my flanks. I was
determined, however, and after donning my debugging armor counter-attacked.
First, I
traced the application to where it barfed, which wasn’t nice, it uses threads so
it won’t freeze (lot of network action).
Eventually I managed to track the error to a method which was adding items to
the TreeListView.
Now, that
was strange, because the exact same code was working just a few minutes
ago when I was using it to insert items after the application loaded.
I
commented the line that called the insertion on start-up, and… woila –
everything works!
Then I
knew that it wasn’t going to be nice. Nevertheless, I set to track the path of
the enemy’s army… err program execution, I mean.
I found
out that I inserted items into the TreeListView before I added columns to it.
Aha, I thought, now I got it! Fixed this, compile and run… but
IndexOutOfBound has managed to sneak behind me again, leaving me with no
other option but following the entire execution path of the program when I
did manage to insert the items (on normal program execution).
Tired and panting, I finished that battle, but I felt victorious, I used the campaign to refactor my forces organization, and I was certain that they would withstand any attack. But over-confidence was my failing, for as I tried once more to head for the territories I desired. I’ve tracked the traitor deep into the enemy lines, until I could no longer follow without risking the dreaded disassembly. But I thought I’d it now, I managed to reinterduce inserting the items without adding columns, so I was confident that all will be fine.
The
exception caught me unaware, leaving me frustrated and screaming.
Time to
regroup and do some thinking, I thought, so I commented the insertion on startup
and tried invading again. But I stopped short, afraid, for there was no
opposition this route.
Now I
knew that I’d a spy on my side, for something was very wrong.
Hungry
for blood, I attempted to throw confusion in the enemy’s lines and checked the
startup data.
I
wondered… could it be… but the changes were made in the application, shouldn’t
it betray me then?
Change
the startup data to match exactly to that created in the application and test.
Success,
I’d a beachhead on the enemy’s front.
But it
was still too early to get cocky; I tried to change the startup data again, and
checked what this might cause.
Treason!
Mayhem! The exception only struck if I tried to insert the most important items.
But how
could the enemy reveal that? The only difference I could see that some of the
items were selected (they were created and then selected on previous, more
successful campaigns).
Impossible, for such a small change to create such drastic measurements! Yet I’d
seen it with my own eyes.
Item. Checked = Group. Selected;
This was the traitor.
If Group.Selected was true, then I was for an unpleasant surprise trying to insert.
But why
should it make any difference?
I tested,
commenting this line and sending scouts ahead. They returned with glowing eyes,
talking about a rich land, if only I could overcome the treason in my own camp…
I could
not get rid of the traitor; he was too dear to me, so I sent him to the front,
after the insertion occurred.
And a
miracle occurred, my surprised attack was successful, and I had scored the enemy
lines in many fronts.
But there
was still the matter of the traitor…
I sent
him to the front with a small unit, and he excelled, and so I slowly enlarged
his command until I finally had so sent him a lieutenant – and then disaster
struck.
Again a
flank attack, directly at my weak spot. And now I’ve located the real tratior.
He was a
small routine, meant to handle ItemCheck called from the TreeListView, the
problem with him was that he used this code:
Group add_grp = Messages.Items[e.Index].Tag as Group;
Apparently, TreeListView (and ListView, its base) first call the ItemCheck
delegate when they get an item with Checked = true and only afterward
they add the item to their Item list.
So
whenever this routine was called, it would generate an IndexOutOfBoundException,
I couldn’t trace it to its real location using StackTrace because I’m using
threads to create a responsive UI.
Conclusions:
- Always have a UnhandledException and ThreadException handlers, that could’ve saved me a long time, I just tested it, and it would’ve give me the real stack trace of the error which would’ve enabled me to solve this in a few minutes.
- I would’ve never caught on to this bug if I wasn’t trying to repreduce the problem and settle on the workaround.
- Debugging multi-threading code is fun as an excrise for the bored mind.
- The only reason that I got this exception from the main thread was that I was using Invoke to update the UI, otherwise, I was into more trouble.
- That was a lovely way to spend the night, thank you very much.
Well, it was too early to brag about open software. I always supported the idea that having the code is nice, but making any useful changes to it is hard.
The reason is simple about the amount of time you can invest in the project. If we take dasBlog as an example, it support FreeTextBox, which is a rich text box editor that output HTML.
All is good, as long as you remain in Internet Explorer. I’ve recently moved to Firefox, just to try the platform, and naturally I thought to use it to post to my blog.
The problem is that while I can post, I can only do it from a normal textbox.
This is acceptable behaviour, since the version of FreeTextBox can’t display on Mozilla’s browsers, it downgrade nicely to a simple textbox.
[Oh, for the days when IE had a natural htmlbox. Netscape/Mozilla would’ve’d to follow, and we had this without the contortions that we use now.]
Now, this is a good and acceptable behaviour on the side of dasBlog, but it’s not acceptable to me.
There is a new version of FreeTextBox that does both IE & Mozilla (including Netscape & FireFox) so I figured what the heck, I can easily add the new textbox and be done with in a few minutes.
Unfortantely, FreeTextBox 2.0 is not code compatible with the version that dasBlog uses. This mean that I’ve to do much more than merely drop the new version.
This means that I’ve to change the code, and this means that I’ve to grok it. Now, dasBlog isn’t that big, but it still have over 45 Kloc thousnads lines of C# code as well as another 25 + thousands lines of html/aspx code.
That is quite a bit of code to grok. In essense, unless I’m willing to dedicate two to three days some time to completely understand what dasBlog does, I won’t be able to touch the code at all.
I sent an email to newtelligence, the company that maitain the code, about it. I think it should be about an hour change for some one who knows the code vs four days for me.
It doesn’t help that dasBlog doesn’t has any documentation regarding its makeup, I’ve to delve into the code to see what it does, and I’m not feeling really up to it right now.
After several months of trying, I’ve finally managed to setup a blog on my site. It wouldn’t have been that hard, if I wasn’t so locked on using .Text blog, unfotuntely .Text require the really expansive Ms Sql Server. I’m hosting this site on shared computer, so I don’t get the privilege to use MSDE, and shelling out for MS Sql Server would cost an arm & leg be quite expansive.
I wanted to use MySql since I got it for free, but .Text doesn’t support it. I wasn’t worried, after all, I’m a programmer myself, and a blog isn’t really that hard to do.
So I did one, using MySql and a nice little engine, if I say so myself, and just when I’m about done – with all the major stuff complete (Rss, CommentAPI, BloggerAPI, etc) and I’ve only error handling minor issues to work on – I uploaded the site to the production server, and then it all fell apart.
Non of the native .Net MySql providers managed to work on the production server. I tried SevenObjects’ MySqlClient, MySql.Net, Direct MySql etc, and nothing works. It all goes very well on my machine, but crach and burn fall apart when I’m trying it on the production server.
I’d to abandon my wonderful project, and decided to look for file storage solutions for a blog. While I was searching, I found dasBlog, which had everything I wanted:
- Free as beer.
- Free as speech – Not as important, but good anyway.
- Used .Net (And more importantly, C#, so I can easily read the code if I’ve to.)
- Didn’t require
expansiveadditionl software. - Highly customizable.
- Has support if I run into some trouble.
All in all, I’m very pleased with it. We are newly aquinted, but I’ve a feeling it’s going to be a wonderful friendship.
And last but not least, a really big thank you should go to Shay & Hagay from Mirshetet for helping me set up the site, I’d all sort of funky problems with permissions, and I’m their first customer that uses .Net, so it’s took a while to remove the rough edges. Nevertheless, they were nothing but gracious and friendly, even though I called them at weird hours during the holiday. Wonderful guys.
Welcome to my humble abode, traveler.
My name is Ayende Rahien, a little known mage that deals with the mysteries of the modern world. I dabble in programming and science fiction and occasionally I attempt a work of fiction. I welcome you to my place, and invite you to share a drink and relax, we've much to discuus.
Do not fear me, for I'm nice.
But remember: "Never anger a wizard, for they are subtle and quick to anger."