Where to implement try catch blocks?

I always try where to place the catch try block. For example, I have a database class with a method that takes two parameters. FindObject (line where the order of the lines). This method executes a sql query with the specified where and order parameters.

In the class, I have the IsUsed property, this property looks like this:

public bool IsUsed { get { ClassA a = new ClassA(); Collection<ClassA> myCollection = a.FindObject("Id = 1",""); if(..) // etc } } 

It doesn't matter if this approach is smart or not, I just want to know where to place the try catch if the execution of the SQL query goes wrong.

Where should I put a try catch so that I can tell the user that something went wrong?

  • In the FindObject method?
  • In the IsUsed property?
  • Where do I call the IsUsed property?
  • Somewhere else? But where
+6
c # error-handling
source share
12 answers

Just catch the exception if you can do something. Otherwise, catch exceptions at the "highest" level in your application and do whatever it takes to process it, including terminating your application.

In user interface applications, event handlers, such as the click handler for the search button, are often the “highest” level. For background services, the “highest” level is often streaming proc or timer callbacks.

  UI application Background service | System Code | | System Code | +----------------+ +----------------+ | Event Handler | <- try/catch here -> | Thread proc | | | | | | ... | | ... | | | | | | Method | <- throw here -> | Method | 

If you allow the exception to propagate back to the system code, you will have an unhandled exception and the application will crash.

Exception handling in a user interface application often involves displaying a message box. Some exceptions are not fatal, and the operation can be repeated (say, if the file is missing or the database query failed), but other exceptions are fatal, and the only option is to terminate the application.

The background service will log the exception and possibly retry the operation. If several attempts fail, the level of logging may increase to attract the attention of operators.

Good practice when it comes to handling exceptions:

  • If you catch the exception and reinstall your own exception, wrap the original exception as an InnerException new exception.
  • If you catch an exception, you might do some cleanup, but restore it because you want it to bubble, and then flip it over with throw without specifying any exception. This ensures that the original stack trace is not destroyed.
  • In most cases, you should only sunbathe the base Exception class in your top-level handlers.
  • Use finally blocks or even better the IDisposable pattern to properly clean your code.
  • Think of exceptions as a “user interface” for the developer and format the exception messages accordingly. If you need a more polished user interface for a less technical user, you probably should hide more technical specifications.
  • Try using exceptions only for exceptions, such as unexpected errors. Do not throw exceptions for common mistakes. Checking for a key in a dictionary should not throw an exception, but instead returns true / false.

To answer your specific question, I do not think that you should catch any exceptions in your property.

+6
source share

I am trying to follow a fairly simple rule: I set up a try..catch block if I can handle the exception in a reasonable way. If there is nothing meaningful in what I can do about the exception, I let it bubble in the calling code.

As a side note, I would avoid making (potentially long) database calls to getter. Usually I try to set only properties or get a value from the support field, allowing other methods to search the database, etc. This will make the code a little more predictable for the person who writes the call code (usually accessing properties is a cheap action, and method calls can often be more expensive). A.

+11
source share

You should place the try-cacth block in the place where you can do something meaningful with the exception caught. How do you register or show it to the user. Do not catch exceptions just for this.

+3
source share

Well, it should be where a try..catch block is needed, and where it can be processed. I assume this will be in the FindObject method here.

So, in the FindObject method, catch and handle a SqlException , for example. If you need to move it to a higher level for better handling, then throw an exception or just fire the bubble.

+2
source share

The only rule I can think of is something like "at the lowest level, where you can really do something useful with information and you don't duplicate the exception handling code."

For example, if you really want to catch all exceptions related to access to the database in the same way, I would create a data abstraction layer (there are many good reasons for this) and put a try-catch block there.

The other extreme will be a web application in which you do not expect any such exceptions, and the exceptions are caught by Elmah. In this case, you will not want to use the try-catch block at all, because this will lead to registration failure.

+2
source share

This is easily responsible: where you can deal with it accordingly.

Ie, at this place, can you make a useful catch-based decision? Can you return something else? Can you say something to someone? Can you transfer the error to a more useful error to another level of your application?

If the answer is yes, then you will catch it. If this is not to all of this, then do not catch it, and let another area do it.

FWIW, IMHO, the implementation of Get too complicated. I think that usually people did not expect property to do such a “job." My opinion, however.

+2
source share

As a rule, the rule :

The try block contains protected code that may throw an exception.

Internally, in your case, you can handle it like this:

 FindObject() { try{}catch{throw;//or throw new Exception("Some info"); } IsUser { try{...a.FindObject("Id = 1",""); return true;} catch(Exception ex){Log(ex); return false;} } 

- EDIT -

This is a response to @controlbreak comment:

MSDN says:

You can explicitly throw an exception using the throw statement. You can also throw an exception caught with the throw statement. It is good coding practice to add information to an exception that is re-selected to provide additional information during debugging.

+1
source share

It depends on where you want to process and to continue processing. Suppose the calling code is responsible for notifying the user, then the calling code is a good code. The calling code may need to ask the user something else after he notifies the user.

Also consider how to redraw the exception that is thrown. If IsUsed is in a class that has nothing to do with databases, and FindObject can SqlServerTimedOutException , it throws the entire call stack. If this schematic is completely confused, catch the exception and flip it like this:

  public bool IsUsed { get { ClassA a = new ClassA(); Collection<ClassA> myCollection; try { myCollection = a.FindObject("Id = 1",""); } catch (SqlServerTimedOutException ex) { throw new MyApplicationException("Cannot evaluate if is in use.", ex); } if(..) // etc } } 

But don't abuse it, because it makes the code pretty ugly. Use caution.

+1
source share

As far as I understand, I put try catch blocks:

  • when finally you need to clear rss resources.
  • when a specific workflow is required in the event of a failure (try the user again, register ...)

As a rule, I allow exceptions to go to the upper level, usually it is a winform control event handler. I use to put a try catch here, using an application-level exception handling method.

Otherwise, when I'm especially lazy, I catch the Application.ThreadException event for MessageBox.Show in the static method of the Main () entry point.

0
source share

Catch errors as early as possible and design an API call so that it can handle failour without using exceptions. Optional exceptions are a threat to stability and five levels, you may not know if there are exceptions in extreme cases, unless the lower API can say that they can fail.

Often you can construct an api to have a result execution state in it that tells the consumer developer that this method may fail and how it will work.

This approach often gives you a point for handling exceptions in the lower parts of the api, instead of just giving them a bubble up to the calling code.

This suggests that there are languages ​​where you can specify that the method will throw exceptions and which exceptions it throws, but you wrote C # that does not have this function.

0
source share

See, if you get any error, set IsUsed to the default value. Something like that:

 public bool IsUsed { get { try{ ClassA a = new ClassA(); Collection<ClassA> myCollection = a.FindObject("Id = 1",""); if(..) // etc } catch { return false;} } } 

Therefore, whenever an error occurs in FindObject, you will create false.

-one
source share

I disagree with most of you.

First of all, I would like to recommend this excellent Joel post: http://www.joelonsoftware.com/items/2003/10/13.html

With that in mind, I use try-catch blocks only as close to WHERE as possible, when they can go wrong.
Obviously, the user interface would love to hear about it. Let this error value than, but not hide the cause of the real problem (by detecting other random errors).

If I understand your code correctly, I think I would use try-catch for the actual request and make IsUsed nullabe to make sure that I realized that it was not assigned a value.

-one
source share

All Articles