views:

206

answers:

3

We are using C# language to develope a Windows application.

Our windows application consists of three layers (UI,Business and DataAccess layer). In Business Layer there are some public (business) methods through which UI communicates wilh Business layer classes. These public methods also have some private methods to implement the required functionality. There are some methods in DataAcess layer which are called from Business layer class.

In this situatuion where should i wrte try-catch? a) In Business Layer Public methods b) In Busyness Layer Private methods c) In DataAccess Layer methods d) In UI methods from where Business methods are called.

A: 

You should use try catch block in each location that in risk to throw an exception that need to be mutable.

Mendy
-1: I don't know what you mean by "mutable", but you should absolutely _not_ catch all exceptions.
John Saunders
By mutable I meant - not affect the next code, and not bubbling up to the user. I need a different word...
Mendy
+3  A: 

You should only handle exceptions when you expect them and want to do something with specific ones. Otherwise, IMO, it is better to let them bubble up the layers so you have a complete stack trace. Even in the presentation tier, I'd be inclined to let errors bubble up (i.e. go to a friendly error screen) unless it was an exception I was specifically expecting.

The general rule with exceptions is to check your inputs in an effort to avoid them, anticipate ones you expect to get and let everything else be exceptional and throw an error. Errors and stack traces are a good thing. They let you know something is wrong and where it went wrong. If a given layer buries its errors, it becomes almost impossible to determine what went wrong.

Thomas
A: 

Exceptions are hard.

You should only catch the ones you expect to happen, and the ones you expect should be caught at a level of abstraction that knows about the task it is trying to complete, rather than a lower one that just knows about a small part of the task.

For example, you have a function which saves temp files. That function calls functions which, say, generate a temporary file name, save the file and then return the temporary file path.

If the file saving function figures out that you gave it a file name that already exists in the directory, then that function shouldn't deal with it. It doesn't know about naming temp files. The function that you call to save a temp file should probably handle it -- it knows about naming the files and it knew that you might create a duplicate one. So, you could generate a new name and try again.

function new_temp_file: try: name = generate_temp_name() save_temp_file(name) return name catch ExistingNameError: return new_temp_file()

If you catch it any higher than that, then higher levels of abstraction know too much about the lower levels.

This is just a simple example, but I hope you get what I am oh-so-ambiguously saying: catch an exception where an exception should be caught.

Carson Myers