Results 1 to 16 of 16

Thread: Confusion with Try ... Catch statement

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Mar 2010
    Posts
    772

    Confusion with Try ... Catch statement

    I am trying to learn the Try ... Catch statements.
    But, the documentation online is very confusing.

    Everywhere I look, their examples are catching SPECIFIC exceptions such as this:
    Code:
    int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (IndexOutOfRangeException e)
        {
            throw new ArgumentOutOfRangeException(
                "Parameter index is out of range.", e);
        }
    }
    Coming from a VB6 background, I really don't understand this.
    As far as I understand, and error handler is a block of code that does NOT know what error has happened.
    Then it figures out what the error is by looking at the error code, and what the description is by looking at the error description.
    Then does something with them for example composes an error message containing the error code and error description and shows that to the user.
    Code:
    ErrHandler:
       ErrorMsg = "Error number " & Err.Number & " occurred: " & Err.Description
       Msgbox ErrorMsg
    How can I write an error handler like that in C#?

    Please help.
    Thanks.

  2. #2
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,525

    Re: Confusion with Try ... Catch statement

    ?!?!?!?
    Code:
    int GetInt(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (Exception e) when (e is ArgumentOutOfRangeException|| e is DivideByZeroException)
        {
            throw new ArgumentOutOfRangeException(
                "Parameter index is out of range.", e);
        }
    }
    EDIT:
    Or

    Code:
    Try
    {
    //Some Instructions
    }
    Catch (DivideByZeroException e)
    {
    //Instructions what to do if Divide By Zero
    }
    Catch (ArgumentOutOfRangeException e)
    {
    //Instructions what to do by Out Of Range
    }
    Catch (Exception e)
    {
    //Instructions what to do in case of ANY other Exception
    }
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  3. #3
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,468

    Re: Confusion with Try ... Catch statement

    Quote Originally Posted by IliaPreston View Post
    Coming from a VB6 background, I really don't understand this.
    As far as I understand, and error handler is a block of code that does NOT know what error has happened.
    That's one reason that VB6 programming can be rather dodgy. You should only ever be explicitly catching exceptions that you can reasonable expect in the current scenario. If you don't know what the exception is then you can't know how to clean up after it so it is not safe to carry on running the app. It might be OK to do so but there's generally no way for you to know, so it might be that you corrupt all your data if you do carry on. When an unexpected are occurs, you ought to log it and exit the app. In VB.NET WinForms, you can do that by handling the applications UnhandledException event. Anywhere else, you should take the time to understand what exceptions could be thrown and code for them explicitly. Anything else is lazy programming, which is something VB6 has a reputation for, deserved or not. It definitely is deserved in those people who just add On Error Resume Next throughout their code.

  4. #4
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,525

    Re: Confusion with Try ... Catch statement

    Quote Originally Posted by jmcilhinney View Post
    *snip* It definitely is deserved in those people who just add On Error Resume Next throughout their code.
    With the exception, that there ARE situations, an OERN is the most simple and elegant solution (Keyword: Adding Items with a Key to a Collection).

    That said: Agreed.
    If you know what Kind of Exception you might expect, code a specific handler for it.
    Doesn't mean you shouldn't have a "generic" (last) Fallback, if you forgot something (Those exceptions are mostly "Bugs")
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  5. #5

    Thread Starter
    Fanatic Member
    Join Date
    Mar 2010
    Posts
    772

    Re: Confusion with Try ... Catch statement

    Quote Originally Posted by jmcilhinney View Post
    That's one reason that VB6 programming can be rather dodgy. You should only ever be explicitly catching exceptions that you can reasonable expect in the current scenario. If you don't know what the exception is then you can't know how to clean up after it so it is not safe to carry on running the app. It might be OK to do so but there's generally no way for you to know, so it might be that you corrupt all your data if you do carry on. When an unexpected are occurs, you ought to log it and exit the app. In VB.NET WinForms, you can do that by handling the applications UnhandledException event. Anywhere else, you should take the time to understand what exceptions could be thrown and code for them explicitly. Anything else is lazy programming, which is something VB6 has a reputation for, deserved or not. It definitely is deserved in those people who just add On Error Resume Next throughout their code.
    Thanks for your help.
    I think my original post was not clear enough.

    This is a snippet of code that I picked from a webpage:
    Code:
          public void division(int num1, int num2)
    	{
             try {
                result = num1 / num2;
             }
    	catch (DivideByZeroException e) {
                Console.WriteLine("Exception caught: {0}", e);
             }
    	finally {
                Console.WriteLine("Result: {0}", result);
             }
    	}
    Well, that is NOT error handling.
    That is implementing the actual logic of the program.
    That is MASQUERADING as error handling without really being one.
    That LOOKS LIKE error handling without being one.
    I am not saying that it is wrong or bad.
    It may be perfectly good. But, it only LOOKS LIKE error handling without being one.

    Somebody else may write it like this:
    Code:
          public void division(int num1, int num2) {
             {
    	     if (num2 == 0)
    	     {
    	         MessageBox.Show("The result is: Infinity");
    	     }
    	     else
    	     {
    	         result = num1 / num2;
    	         MessageBox.Show("The result is: " + result);
    	     }
             }
    I am not saying that this is a better way of writing it.
    I am saying that this just another way of doing it (maybe a less good way of doing it).
    But, I am trying to say that the above catch statement is the implementation of part of the LOGIC of the program as opposed to being a real error handler.


    Now let's say I write a huge method and take care of all the pitfalls that I can think of (by employing try ... catch or by employing if ... else or by any other way).
    There is always a chance that I might miss something.
    Nobody can claim that they can anticipate ANY and ALL the pitfalls that may affect their program.
    If something really really unpredictable happens, the program crashes (crash-landing !!!)
    But, if I can write a genuine error handler, I can log the error and abort and close the program with all the due care that needs to be taken (soft-landing)

    When an unexpected are occurs, you ought to log it and exit the app
    That is exactly what I am talking about.
    Plus: Before I log it and exit the app, I have to implement into my app a mechanism to catch that unexpected error.
    This code:
    Code:
        catch (IndexOutOfRangeException e)
        {
            throw new ArgumentOutOfRangeException(
                "Parameter index is out of range.", e);
        }
    does NOT catch that unexpected error (It only catches "index is out of range" error).
    So, how do I catch unexpected errors?

    And also in terms of logging it (or just showing a message or whatever), in VB6 there is a very straightforward way of obtaining the details of the unexpected error, so that those details can be logged (or displayed). That straightforward way is to get the Err.Number and Err.Description of the Err object.
    But, I don't know how to get those details (the details of the error such as error description, etc) in C#.

    And also in terms of catching, again, in VB6 it is very easy. The following VB6 code shows how to catch the error and how to obtain the error details:
    Code:
       On Error GoTo ErrHabdler
       ...
    ErrHandler:
       ErrorMsg = "Error number " & Err.Number & " occurred: " & Err.Description
       Msgbox ErrorMsg
    But, in C#, I don't know how to do that.

    Also, Zvoni said: (thank you Zvoni)
    Zvoni: Doesn't mean you shouldn't have a "generic" (last) Fallback,
    That is true. That "generic" (last) Fallback is the main premise of this thread.
    Zvoni: if you forgot something (Those exceptions are mostly "Bugs")
    Of course those are bugs.
    My whole point is that if bugs happen, I should lead my app to a safe soft-landing instead of leaving it to the mercy of a crash-landing.

    Please advise.
    Thanks again for everybody's help.
    Ilia

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,468

    Re: Confusion with Try ... Catch statement

    In your methods, you only write code to catch expected exceptions. You then have a global exception handler in the form of one or more event handlers, which will be executed when an unexpected exception goes uncaught. If you search for "global exception handler c#" then you'll find info on how to do that. Off the top of my head, I think you need to handle Application.UnhandledException and AppDomain.ThreadException or something like that.

  7. #7

    Thread Starter
    Fanatic Member
    Join Date
    Mar 2010
    Posts
    772

    Re: Confusion with Try ... Catch statement

    Quote Originally Posted by jmcilhinney View Post
    ... You then have a global exception handler in the form of one or more event handlers, which will be executed when an unexpected exception goes uncaught. If you search for "global exception handler c#" ...
    I am definitely going to do that search.
    But, before I do so, let me understand the try ... catch as well.

    I just wrote a simple method like this:
    Code:
            private void NumDivide(double Num1, double Num2)
            {
                double Result;
                try
                {
                    Result = Num1 / Num2;
                    txtDetails.Text = "The result is: " + Result;
                }
                catch (DivideByZeroException e)
                {
                    txtDetails.Text = string.Format("Exception caught: {0}", e);
                }
            }
    And I call it like this:
    Code:
            private void btnTest004_Click(object sender, EventArgs e)
            {                    //          Testing the Try ... catch technique of error handling
                double Num1 = 27.348;
                double Num2 = 0;
                NumDivide(Num1, Num2);
            }
    When I run it, the exception does NOT happen !!!
    When I run it, it prints:
    The result is: ?
    screen print:
    https://i.imgur.com/1T49pbD.jpeg

    I even run it step by step, and it does not lead to an exception. It just carries out the division by zero !!!
    Why does the exception NOT happen?

    Please advise.
    Thanks.
    Last edited by IliaPreston; May 4th, 2024 at 07:01 AM.

  8. #8
    PowerPoster
    Join Date
    Nov 2017
    Posts
    3,210

    Re: Confusion with Try ... Catch statement


  9. #9
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,525

    Re: Confusion with Try ... Catch statement

    Have you actually looked at the last catch in my second code sample?
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Mar 2010
    Posts
    772

    Re: Confusion with Try ... Catch statement

    Quote Originally Posted by Zvoni View Post
    Have you actually looked at the last catch in my second code sample?
    Thanks Zvoni

    Actually no.
    It is only now that I saw that.
    Initially when I opened this page after initially having opened this thread, there were a number of other responses after your post, that is why I read through your post too fast and missed that last "catch".
    Certainly my mistake.
    Now, I see that it was really very important and very informative.

    I just tried to compare it with other catch statements (the specific ones).

    Here is the code for SPECIFIC catch statement:
    Code:
            private void NumDivideInt(int Num1, int Num2)
            {
                double Result;
                try
                {
                    Result = Num1 / Num2;
                    txtDetails.Text = "The result is: " + Result;
                }
                catch (DivideByZeroException e)
                {
                    txtDetails.Text = string.Format("Exception caught: {0}", e);
                }
            }
    Code:
            private void btnTest005_Click(object sender, EventArgs e)
            {                    //          Testing the Try ... catch technique of error handling with type int & specific error handling
                int Num1 = 8;
                int Num2 = 0;
                NumDivideInt(Num1, Num2);
            }
    And here is the code for GENERAL catch statement (the last catch in your second code snippet):
    Code:
            private void NumDivideIntGenErrH(int Num1, int Num2)
            {
                double Result;
                try
                {
                    Result = Num1 / Num2;
                    txtDetails.Text = "The result is: " + Result;
                }
                catch (Exception e)
                {
                    txtDetails.Text = string.Format("Exception caught: {0}", e);
                }
            }
    Code:
            private void btnTest006_Click(object sender, EventArgs e)
            {                    //          Testing the Try ... catch technique of error handling with type int & general error handling
                int Num1 = 8;
                int Num2 = 0;
                NumDivideIntGenErrH(Num1, Num2);
            }
    In both cases the result is exactly the same:
    In both cases, that "e" is a string that contains the error description, and my code:
    Code:
                    txtDetails.Text = string.Format("Exception caught: {0}", e);
    prints that description.

    So, it begs the question as to why does anybody ever use those specific catch statements?
    If you only have ONE catch statement like this:
    Code:
                catch (Exception e)
                {
                    ......
                }
    it will catch any and all errors, and you can display the error description (or log it or do whatever).
    So, why would anybody want to do separate catch statements for different errors?

    Please advise.
    Thanks

  11. #11
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,525

    Re: Confusion with Try ... Catch statement

    Quote Originally Posted by IliaPreston View Post
    So, why would anybody want to do separate catch statements for different errors?

    Please advise.
    Thanks
    Because there might be situations for SPECIFIC Exceptions you can actually "repair" or you want to execute different code

    e.g.
    "IndexOutOfRangeException":
    if you catch this specific exception, within that specific Error-Handler:
    1) you could set the Index to the last valid Entry (or the first),
    2) log that Error,
    3) play a soundfile "blow Raspberry to user.mp4"

    "DivideByZeroException"
    if you catch this specific exception, within that specific Error-Handler:
    1) Return the Focus back to the Textbox
    2) Show MessageBox "Bloody Idiot. Did you sleep in Math during School?"

    "Exception" (last Fallback for all other exceptions)
    1) Show Message "Ooooopppss! Something went wrong. Check your Log"
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  12. #12
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,569

    Re: Confusion with Try ... Catch statement

    It's hard to see because the example is too simple, contrived, and really should be written differently:

    Code:
            private double NumDivide(double Num1, double Num2)
            {
                double Result;
                if(Num2 == 0) {
                   throw new DivideByZeroException();
                }
                return Num1 / Num2;
            }
    Now your calling code should have the try catch in it... but... that's beside the point...

    It's really about establishing and showing the pattern. Functions you write that does division should protect itself against DBZE... but what if that function is in code you DIDN'T write. What if there's a library that you're using that either throws the DBZE in the manner I showed above, or, for what ever reason, doesn't check but just does the division and incidentally throws the DBZE.

    I've got code where I could get back one of three different types of errors... And depending on what that error is, I handle them differently. To do that, I have three catches to handle those specific errors. Each one does it's own thing and then either returns or continues depending on the situation.

    I might get a 404 or 503 (service unavailable) which is an HTTP Exception ... or I might get a File Not Found error ... I may want to handle those differently, log it differently, and certainly display a different message to the user... Multiple specific catches allow me to do that.

    Also, it's best practice that you catch specific errors so that you don't unintentionally hide other errors that could be detrimental. Say, for instance, hiding a Null Pointer Error on an object that has no business being NULL.


    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  13. #13

    Thread Starter
    Fanatic Member
    Join Date
    Mar 2010
    Posts
    772

    Re: Confusion with Try ... Catch statement

    Thanks for all the great help and advice.

    As I keep working with the try ... catch statement, I paid attention to this:
    Code:
                catch (DivideByZeroException e)
                {
                    ......
                }
    or:
    Code:
                catch (Exception e)
                {
                    ......
                }
    I placed the cursor on e, then right clicked and clicked on "GoTo Definition"
    It went to itself
    I placed the cursor on DivideByZeroException, then right clicked and clicked on "GoTo Definition"
    It went to a class

    So, I conclude that
    Code:
                catch (DivideByZeroException e)
                {
                    ......
                }

    is a variable declaration.
    The variable e of type DivideByZeroException (which is a class) is declared in here.

    Also, if I write a dot (.) after the e, intellisense opens a dropdownbox for me that has "Message", "InnerException", "Source", etc.

    Therefore a statement like:
    Code:
                catch (DivideByZeroException e)
                {
                    txtDetails.Text = string.Format("Exception caught: {0}", e);
                }
    should NOT work because e is NOT a string or something convertible to a string. It is a whole object with multiple properties.

    But that statement works.
    Why?
    Why does it work?

    Also, I changed the code to the following:
    Code:
                catch (DivideByZeroException e)
                {
                    txtDetails.Text = string.Format("Exception caught: {0}", e) + "\r\n\r\n\r\n" + string.Format("Exception caught: {0}", e.Message);
                }
    And here is the result:
    Exception caught: System.DivideByZeroException: Attempted to divide by zero.
    at Test002SqLite.Form1.NumDivideInt(Int32 Num1, Int32 Num2) in D:\Dev\VCS\Tests\Test002SqLite\Test002SqLite\Form1.cs:line 743


    Exception caught: Attempted to divide by zero.
    which is interesting.

    But, still I don't understand why
    Code:
                catch (DivideByZeroException e)
                {
                    txtDetails.Text = string.Format("Exception caught: {0}", e);
                }
    works?
    It shouldn't work (because e is an object with multiple properties), but it works.
    Why?

    Please advise.
    Thanks

  14. #14
    PowerPoster PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Pontypool, Wales
    Posts
    2,547

    Re: Confusion with Try ... Catch statement

    Quote Originally Posted by IliaPreston View Post
    should NOT work because e is NOT a string or something convertible to a string. It is a whole object with multiple properties.

    But that statement works.
    Why?
    Why does it work?
    Pretty much everything in .net is convertible to a string, all objects have a .ToString() method for exactly this reason. When you are using the variable e in that String.Format it is simply calling .ToString on the variable.

  15. #15
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,468

    Re: Confusion with Try ... Catch statement

    Quote Originally Posted by PlausiblyDamp View Post
    Pretty much everything in .net is convertible to a string, all objects have a .ToString() method for exactly this reason. When you are using the variable e in that String.Format it is simply calling .ToString on the variable.
    Further to that, the Object.ToString method simply returns the name of the current type, so any class that doesn't override the ToString method will return its type name from that method. The Exception class does override the ToString method, returning a String containing the Message property value and text from the StackTrace if the current exception and the InnerException. Generally speaking, you should use the result of that ToString method when logging an exception.

  16. #16
    Fanatic Member BenJones's Avatar
    Join Date
    Mar 2010
    Location
    Wales UK
    Posts
    669

    Re: Confusion with Try ... Catch statement

    this link may provide some info as well
    https://www.tutorialsteacher.com/csh...ption-handling

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width