Link to home
Create AccountLog in
C#

C#

--

Questions

--

Followers

Top Experts

Avatar of rwheeler23
rwheeler23🇺🇸

C# proper placement of try catch

Using C#, what is the proper placement of the try/catch block using this example?

Should it go outside the using or just before the ExecuteQuery?


private void Clear_Payments()
{
    using (SqlCommand cmd = new SqlCommand("DELETE FROM [dbo].[APMC_LOAD_LOG] WHERE WasImported = 0", dataConnection))
    {
        cmd.CommandType = CommandType.Text;
        cmd.ExecuteNonQuery();
    }
}

Zero AI Policy

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of Alex [***Alex140181***]Alex [***Alex140181***]🇩🇪

If you want to add exception handling here, I suggest you resolve the "using" into a "classic" trya-catch-finally block. Under the hood, C# generates a try-finally bytecode when using "using" (in contrast to Java's "try-with-resources block" -> here, Java generates a full try-catch-finally block and you're able to deal with exception even if you're using that construct).

If you're going to wrap a try-catch around this, you might end up with "redundant" finally stuff! Keep that in mind ;-)


https://social.msdn.microsoft.com/Forums/en-US/7527b0a5-7ba3-4337-b4b0-46d576126df5/exception-handling-in-a-using-statement?forum=csharplanguage


https://blogs.infosupport.com/the-c-using-statement-and-suppressed-exceptions-compared-to-java-7-try-with/


Avatar of Mlanda TMlanda T🇿🇦

If you're going to wrap a try-catch around this, you might end up with "redundant" finally stuff! Keep that in mind ;-)


I'm not sure I entirely agree with this Alex. With the "using" statement, yes, it basically generates a try-finally block, with the finally block disposing the "using" variable. However, this means the using variable is declared outside the try-finally block (generated by the "using"). So you actually do need to wrap the entire using in a try-catch-finally block which can catch any errors with the initialization of the using variable itself. Borrowing from the link you shared, this would perhaps be the best way to do it.

try
{
    using (StreamReader sr = File.OpenText(path))
    {
        // do something with streamreader
    } // StreamReader disposed here.
}
catch (FileNotFoundException fnfex)
{
    // do some error handling here.
}

Open in new window



I did NOT say, that you can't do it like this (surrounding the using with a try-catch), but if you need to access "sr" after the using, this object has already been disposed! Keep that in mind ;-)


Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Avatar of ste5anste5an🇩🇪

In the case of executing a SQL command, there are two external error sources:

1) The opening of the SQL connection.
2) The execution of the SQL command.

Thus, a single try/catch can hide exceptions.

Thus, a single try/catch can hide exceptions.

Unless the try-catch block is wrapped around both ;-)


Avatar of Dorababu MDorababu M🇮🇳

Try something like this


private void Clear_Payments()
        {
            try
            {
                using (SqlCommand cmd = new SqlCommand("DELETE FROM [dbo].[APMC_LOAD_LOG] WHERE WasImported = 0", dataConnection))
                {
                    cmd.CommandType = CommandType.Text;
                    try
                    {
                        cmd.ExecuteNonQuery();
                    }
                    catch (SqlException ex)
                    {


                    }
                }
            }
            catch (Exception ex)
            {
            }


        }

Open in new window



Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of rwheeler23rwheeler23🇺🇸

ASKER

I believe the question here is a matter of scope. I may be wrong but the only thing that can cause and error would be the cmd.ExecuteNonQuery(). I discovered this when I spelled WasImported wrong. It wasn't until it tried to execute the command when the error occurred.


ASKER CERTIFIED SOLUTION
Avatar of Mlanda TMlanda T🇿🇦

Link to home
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.
Create Account

Avatar of rwheeler23rwheeler23🇺🇸

ASKER

and my learning continues. Thanks for this insight.


No need for nested try-catch here! I'd rather do sth like this:

private void Clear_Payments()
        {
            try
            {
                using (SqlCommand cmd = new SqlCommand("DELETE FROM [dbo].[APMC_LOAD_LOG] WHERE WasImported = 0", dataConnection))
                {
                    cmd.CommandType = CommandType.Text;
                    cmd.ExecuteNonQuery();
                }
            }
            catch (SqlException ex)
            {             }             catch (Exception ex)             {             }         }

Open in new window



Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Avatar of rwheeler23rwheeler23🇺🇸

ASKER

Looking at Alex's solution it appears to have one try and two catches. Is this permissible? Does this mean a sql exception is caught by the first catch and some other error would be caught by the second?

Avatar of Mlanda TMlanda T🇿🇦

Yes. You can have multiple catch statements. One try, multiple catch, and one final. The catch statements allow you to handle specific Exceptions in specialised ways. Suppose you had code where you were expecting an ArgumentException, a FileNotFound and any other error, you would handle them

try {
}
catch ArgumentException { /*handle the argument exception */ }
catch FileNotFound { /*handle the filenot found*/ }
catch Exception { /*do something for any other error*/ }

Open in new window

Note that there is an order to this. You start with the most specific errors, then more general errors at the bottom. So for example,

try {
}
catch Exception { /*do something for any other error*/ }
catch ArgumentException { /*handle the argument exception */ }
catch FileNotFound { /*handle the filenot found*/ }

Open in new window

This would mean that the catch ArgumentException and catch FileNotFound would never execute because the catch Exception catches all of them.


Avatar of rwheeler23rwheeler23🇺🇸

ASKER

Is there a list of these specific errors and the order of their severity?

Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Is there a list of these specific errors and the order of their severity? 

As always, it depends on what you use/do. 

If you use a file system related class, you may get file i/o related exceptions; when using web sockets you may get socket timeout or read timeout exceptions etc...


During the implementation, you usually "see" (also with the help of modern IDEs) which exceptions might occur and then you decide which of them you want to handle and which may be dealt with by the more generic "Exception" class. The latter is usually the "core" or super class of all other specific exceptions.


There is no order of severity, it's rather a question of bubbling thru the possible exceptions down/up to THE "Exception" when there is no specific handler (aka catch block)...


Further links related to this topic:

https://blog.ndepend.com/the-proper-usages-of-exceptions-in-c/


https://kumarashwinhubert.com/exception-handling-in-csharp-throw-or-throw-ex


Avatar of rwheeler23rwheeler23🇺🇸

ASKER

All of these tips were helpful.
C#

C#

--

Questions

--

Followers

Top Experts

C# is an object-oriented programming language created in conjunction with Microsoft’s .NET framework. Compilation is usually done into the Microsoft Intermediate Language (MSIL), which is then JIT-compiled to native code (and cached) during execution in the Common Language Runtime (CLR).