views:

72

answers:

3

I have an user control, which contains multiple methods and each of these methods has a try-catch block. I catch only one type of exceptions, for example ArgumentException. Update - I don't catch one exception but multiple exceptions which I defined.

Each of these methods handles the ArgumentException the same way, so I have redundant code.

Can I catch ArgumentException in one place so that all methods in the user control would use it?

Update1: The application is in use in the production and it is used by many people who are not very familliar with computers. Simplified - they have to insert a lot of numbers into the database (with the help of hand-held optical scanner) and of course they make mistakes. There is at least 8 common exceptions (wrong size, wrong type,...) and in my business logic I catch all these exceptions and throw them to GUI. Because the environment, where the application is installed, is very lousy, I play a loud error sound and display the error message.

Because of the business logic, they have several options to insert these numbers, so the same error catching logic is in multiple methods all across the user control.

Update2: actually I'm not catching ArgumentException but my own exceptions, for instance CodeFormatException, CodeDoesntExistException, CodeNotInTheSelectedRollException etc.

+2  A: 

You can get this piece of code into some validating arguments function and call it at the start of your function's.

Svisstack
+1  A: 

If you have unmanaged code rights, you could override the WndProc method of your UserControl (if you don't have unmanaged code rights, the application will throw an exception as soon as your UserControl class is first referenced). The keyboard, mouse, and painting events are caused by messages that are processed in the WndProc, so call the base implementation of that method in a try...catch to handle those events. For the others, you will have to wrap them each in a try...catch, but you can move your catch logic to a helper method that is called from all catch blocks so you are not duplicating code.

Edit: Actually, I think something like this might be better. It doesn't require permissions and you could use it for events fired from other controls on your UserControl as well:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        this.Load += new TryCatchHandler(new EventHandler(this.Form1_Load)).EventHandler;
        this.MouseClick += new TryCatchHandler(new MouseEventHandler(this.Form1_MouseClick)).EventHandler;

        this.button1.Click += new TryCatchHandler(new EventHandler(this.button1_Click)).EventHandler;
    }

    private void Form1_MouseClick(object sender, MouseEventArgs e)
    {
        // ...
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        // ...
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // ...
    }

    private class TryCatchHandler
    {
        public Delegate handler;

        public TryCatchHandler(Delegate handler)
        {
            this.handler = handler;
        }

        public void EventHandler(object sender, EventArgs e)
        {
            try
            {
                this.handler.Method.Invoke(this.handler.Target, new object[] { sender, e });
            }
            catch (ArgumentException exc)
            {
                // ...
            }
        }
    }
}
Mike Dour