Hossein
Hossein

Reputation: 25924

Can we create an exception class in c# which can infer the type of exception and show the relevant info accordingly?

I have heard and read that we need to know in Code time what exceptions we are going to be confronted with and place the necessary catches.

Now cant we infer the type of the actual exception that has just happened from the Exception class and then cast that and get the needed info? for example consider this:

private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //try doing something to generate and exception
                int blah =8 / Convert.ToInt32(txtBox.Text);
            }
            catch (Exception ex)
            {
                //ex.GetType().Name
                //getting the type and casting it according to the retrieved name
                //and finally showing the more detailed info of the occurred exception
               //for example like this?
               //MessageBox((ex.GetType())ex).Message);  
            }
        }

This is just a sample to convey my meaning, suppose if that is possible we make that a custom class which inherits from Exception and do the needed work for such a purpose.

Cant we do such a thing? If we can how can we cast it ? and if it cant be done why is that?

Upvotes: 3

Views: 186

Answers (5)

Leandro
Leandro

Reputation: 1555

The short answer to your question is: yes, of course (kind of). A more meaningful answer would go through all the pain of trying to explain how to do proper exception handling. There's close to an infinite number of articles on the web about this subject, plus a handful of practical valuable (and pricey) books for that matter. A question in SO could set you in the right direction, but nothing more.

Your sample code is quite trivial, as is the norm for examples. The ugly truth is you almost never face so simple problems in day to day software development. So, it is difficult to make a story and illustrate a somewhat complex idea over a simplistic and specific case. There have been many attempts at solving what you allude in your question, like the Exception Handling Application Block, for instance.

But there's an essential difference between handling an exception to take note of its existence for letting a user/developer know exactly what is wrong in an application, and on the other hand handling exceptions to do some kind of unorthodox control of a program's execution flow.

Swallowing an exception is unacceptable under almost every circumstance. There's quite a limited number of exceptions (pun intended) to that rule. You should catch exceptions only when you can recover from the error without negatively affecting the utter flow of the program, not just because you want to "handle" them. That's basically the reason why I disagreed with the solutions given by @martin-lariviere and @andrei.

When you catch an exception and don't handle it well, you might be inadvertently affecting the called method's postconditions, which might indirectly affect the calling code's execution because of unmet assumptions made about the called piece of logic. In turn, all that could lead to an unstable state of the program. In short: a latent demon lurking around ready to bite you in any moment, eager to corrupt some data (at least).

The sample method is void, but what if it were something else? What if an exception occurred in the middle of an operation needed to determine some return value? How would you handle such exception? You have basically two options:

  • (Dangerous) Swallow the exception, use some default value for the calculation and return a potentially inaccurate result that might "astonish" the calling code (and the user). Even in this situation, it would be wise to log the error at least. Your "future you" might be thankful someday if he had to trace a bug caused by this particular misbehaviour. It might be safe, but that would depend on the particular method being implemented (specifically its postconditions and invariants).

  • (Delicate) Allow the exception to propagate to the calling code; either "as is" or wrapped in some other exception. In this situation you might log the error, but it's not really necessary. Nevertheless, you might take action to ensure that some resources are properly released and maybe some half-initialized objects or mid-modified data goes back to some stable state again.

Either option requires that sensible judgment calls be taken to implement a proper exception handling strategy, and that should be considered for every operation that might throw an exception! Obviously, it's something every developer should take into account every time they type any code. It's brutal.

So, there's no easy correct answer to your question. Maybe you want a pattern to solve once and for all the things to do in the second option (Delicate). Sadly, there's none. Maybe in a second post I could elaborate on that: error conditions, exceptions and notifications/alerts to the user in the UI. That is a tough subject, and this "answer" is already awfully verbose.

Upvotes: 2

AWinkle
AWinkle

Reputation: 673

To give an example of Chris Cudmore's suggestion

        try
        {

        }
        catch (System.FormatException FormatEx)
        {
            //logic here
        }
        catch (Exception ex)
        {
            //generic catch-all
            MessageBox(ex.Message);
            throw;
        }

Most of the time, you want to know the type of exception before hand so you can handle that exception specifically (for any cleanup/recovery tasks), not so you can access base members such as Exception.Message.

Upvotes: 2

turdus-merula
turdus-merula

Reputation: 8854

If you want, you can delegate exception handling logic to some well-defined module, whose purpose is to... handle exceptions :) Maybe this way...?

try {
    // code that throws something
} catch (Exception e) {
    myExceptionHandlingStrategy.handleException(e);
}

where myExceptionHandlingStrategy is an instance of MyExceptionHandlingStrategy, a module that exposes the interface IExceptionHandlingStrategy, defined (probably) as follows:

interface IExceptionHandlingStrategy {
    void handleException(Exception e);
}

Then, in certain implementations of that interface (you may have a lot of them), you are free to do something like this:

if (e is SomethingBadException) {
    // show some message
} else if (e is SomeOtherKindOfException) {
    // do something else instead
} else {
    throw new CannotHandleThisException(e);
}

PS: NO reflection :)

Upvotes: 2

Selman Genç
Selman Genç

Reputation: 101681

I think it is not necessary but here is an example:

try
{
    int[] numbers = new int[2];

    numbers[6] = 345;
}
catch (Exception ex)
{
      Type t = ex.GetType();

      var props = t.GetProperties();

      foreach (var p in props)
      {
          Console.WriteLine(p.Name + " : " + p.GetValue(ex));
      }
}

Upvotes: 1

Martin Larivière
Martin Larivière

Reputation: 264

Not sure what your intentions are.
Your ex variable should hold the error messages generated along with the list of the inner ones.
If you want to have the name of the type you can do the following :

catch (System.Exception _ex)
{
    switch (_ex.GetType().FullName)
    {
        case "System.FormatException":
            *//Do what you want in case of a FormatException error...*
            break;
        case "System.*other type*":
            *//Do what you want in case of a ...*
            break;
        default:
            break;
    }
 }

Upvotes: 0

Related Questions