Click here to Skip to main content
15,918,125 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I would like to save a lot of time and space in my C# application not to surround each single line of code with a "try...catch" construct to avoid errors. It obscures my code and to type it each time is tiring off. I seek to do some global error handling.

Example (VB 6): On Error Resume Next. (=error handling done for whole application with a one-liner. Code get executed no matter what!)

Is there something alike for C#?
And then I would need some more error information on the exceptions. Just to know that there was an exception of type XY is not enough for me.
I need the error number (e.g. error no. 56) and the error line (error in line 578 e.g.) (code line number where the error happened) and function name (e.g. "void form_load(...)") where the error was triggered.
C# seems not to supply such informations on exceptions. So I have a hard time to figure out, what the error is about. Any ideas on this?

What I have tried:

C#
try
{
//here the code line to handle
}
catch(Exception Ex1){MessageBox.Show(Ex1.Message); Process.Start("shutdown" "-f");}


This provides me not enough information about the error. I would like to see the error number (e.g. error no. 65) and the error code line (e.g. error in line 578) to have more tracking informations about what exactly happened.

Then I would need a global error handling on whole application, not this per line thing all the time.

Any solutions or better global error handling commands on this?
try...catch is definitely not the thing for me to go.

Any logoff dialog before shutting down the whole system on error would be also nice.
Posted
Updated 12-Apr-16 3:59am
v2
Comments
Richard Deeming 12-Apr-16 10:09am    
Shutting down the computer every single time an error occurs is a terrible idea! Any program that tried to do that would quickly be uninstalled from any system, and a refund demanded.

You seem to be stuck in "VB6-mode". Forget what VB6 did, and embrace proper structured exception handling.

Don't wrap each line of code in a try..catch block. Instead, wrap a logical section of code which could throw an exception which you can handle in a try..catch block, catching the specific exception types that your code can handle, and handling them appropriately.

Let any exceptions that you can't handle fall-through to the calling code.

Have a top-level try..catch block on your entry-point which logs unhandled exceptions and terminates the program. NB: DO NOT try to shut down or restart the computer just because your program has an unhandled exception!

Use the StackTrace to see where the exception was thrown, and the chain of methods that were called to get there. (Much better than VB6's Err object!) Look at the InnerException to see if the exception you've caught is a wrapper for a lower-level exception.

SEH is far superior to VB6's error handling, if only you'd embrace it properly! :)
Sergey Alexandrovich Kryukov 12-Apr-16 11:55am    
VB6 does not have structural exception handling. That means, it has nothing.

With .NET, you don't need anything as in VB6.

—SA
Richard Deeming 12-Apr-16 14:22pm    
It's far from "useless" - the combination of the exception type and message provides far more detail than error 42. Combined with the additional detail provided by the exception class, it gives you everything you need to diagnose and resolve the error.
Richard Deeming 12-Apr-16 14:23pm    
For Windows Forms, use Application.Exit(); to terminate the application.

Alternatively, use Environment.Exit(exitCode); to terminate the process and return an exit code to Windows.
Richard Deeming 12-Apr-16 15:52pm    
Use one or the other; any code following either method call will not execute.

Remove the "shutdown" command, since you don't want to shut down the computer.

The Exception class can provide a great deal of detail if you need it, including the line number and a complete stack trace. Examine the output from this code snippet for a demonstration:
C#
private void input_btn_Click(object sender, EventArgs e)
{
    try
    {
        int x = 0;
        int y = 1;

        int z = y / x;

    }
    catch (Exception ex)
    {
        Console.WriteLine("--------------------");
        Console.WriteLine(ex.Message);
        Console.WriteLine("--------------------");
        Console.WriteLine(ex.ToString());
        Console.WriteLine("--------------------");
        Console.WriteLine(ex.StackTrace);
    }
}

For better global error handling techniques then this article is a must-read Exception Handling Best Practices in .NET[^]

As is this Vexing exceptions | Fabulous Adventures In Coding[^]
 
Share this answer
 
Comments
Richard Deeming 12-Apr-16 10:01am    
What? Did you even try the code? Of course it handles the exception - that's what the catch block is for!

The information about procedures and line numbers comes from the stack trace - ex.StackTrace. That will tell you exactly where the exception was thrown, and the methods that were called to get to that point. It gives you a lot more information than VB6's Err object.

The calculation in the answer is just an example of code that throws an exception.
CHill60 12-Apr-16 11:17am    
As @RichardDeeming has pointed out - the code I presented was not meant to be a solution - it was for you to see just how much more information is available in the Exception object than just the message.
The actual solution is given in the two links I included.
Richard Deeming 12-Apr-16 14:19pm    
catch (Exception ex)
{
   MessageBox.Show(ex.ToString());
   Application.Exit();
}


It's still a bad idea to close your application on every exception - there are plenty of exceptions which you can handle gracefully.
Sergey Alexandrovich Kryukov 12-Apr-16 12:02pm    
You cannot do programming without learning how structural exception handling works; and right now you don't have a clue. Do yourself a big favor, learn the concept first.
—SA
Sergey Alexandrovich Kryukov 12-Apr-16 12:03pm    
I voted 4; and it's not 5 only because this is not what inquirer can understand well right now; he rather need to learn the whole concept.
—SA
I am assuming you want to catch and do something with all unhandled exceptions within your code. I will leave it to you to put the proper using statements at the top of your files.

Do something like this:

In your main within program.cs near the beginning of the function:

C#
Application.ThreadException += new ThreadExceptionHandler(UnhandledExceptionEventHandler);

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);


Then, write your handlers like this:

C#
public void CurrentDomain_UnhandledException(object sender,  UnhandledExceptionEventArgs e)
{
    ExceptionHandler((Exception)e.ExceptionObject);
}

public void UnhandledExceptionEventHandler(object sender, ThreadExceptionEventArgs e)
{
    ExceptionHandler(e.Exception);
}

public void ExceptionHandler(Exception e)
{
    string result = FormatException(e, string.Format("Information: {0}\n\n", Assembly.GetEntryAssembly().GetName()));


    // Do what you want with the result here.
}

public string FormatException(Exception e, params string[] information)
{
    Exception ex = e;
    StringBuilder sb = new StringBuilder();

    if (information != null)
    {
        foreach (string s in information)
            sb.Append(s);
    }
    while (ex != null)
    {
        sb.AppendLine(ex.GetType().ToString());
        sb.AppendLine(ex.Message);
        sb.AppendFormat("\n\nStack Trace:\n{0}", ex.StackTrace);
        ex = ex.InnerException;
        if (ex != null)
             sb.AppendFormat("\n\nInner Exception:\n\n");
    }
    return sb.ToString();
}
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 12-Apr-16 12:01pm    
Good, but this answer assumes that the inquirer uses System.Windows.Forms. WPF has different but similar system, as well as nearly all modern non-nonsense library.
However, our inquirer is totally lost in the topic, it can hardly practically help. If a person needs to learn what is structural exception handling, it's like creating a new cortical fold. :-)
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900