简体   繁体   中英

Complete code in try/catch block

I want to know, is it a good practice to place complete code inside a try block or I should place only the code which I feel it will cause a specific exception ?
And should I catch basic Exception always

Code 1 : complete code in try block

myFunction(){
 try{
   .........
   Code with chance of OneException 
   .............
 }catch(OneException e){
  ............
 }catch(Exception e){
   ..............
 }
}

Code 2 : Only the Code with chance of Exception in try block

myFunction(){
  .......
  try{
   Code with chance of OneException 
  }catch(OneException e){
  ............
  }
  ............
}

Code 3 :Should I catch Exception always

    myFunction(){
      .......
      try{
       Code chance of OneException 
      }catch(OneException e){
      ............
      }catch(Exception e){
       ..............
      }
      ........
   } 

Out of this (code1, code2 and code3) which one is the best?
I'm mainly concern with java and C++ coding

Generally speaking, you should only catch exceptions you're interested in and which you can handle . That is...catch an exception where you can do something st the user doesn't perceive the problem or when it is explicitly necessary to tell the user about the problem.
For all other exceptions, let them pop up with all their details (stacktrace etc..) which you obviously log. Note, obviously this doesn't mean the user should also see that exception output but rather a generic error.

Told this, I assume that when you write "Code chance of OneException" you know how to handle OneException, but not Exception, right? So then...only handle OneException.

Always catch exactly what you have to and no more. No matter how much we try, we cannot make our code completely "idiot proof". If someone passes you something which will cause some random error, then it is their job to handle it. If our code handles someone else's exception that has far too much risk of being an unexpected side-effect.

As far as what code to place where: code before the line which could throw the Exception will be run either way, so it does not really make sense to have it inside the try block and before the code which throws. Code after the potential exception should be placed between try and catch if and only if it depends on the exception generating code. So, if your database connection call can fail, place all of the database queries inside the try block.

Limiting the "time" spent in a try...catch makes it easier to read and less prone to accidental catching. I can't tell you how many hours have been lost because someone decided to catch an Exception which should have propagated.

  • a) It is bad practice, to place complete code inside a try block.

    • a1) Beside of catching exceptions, a try-block is a documentation where an exception might happen. So place it close to the cause, you have in mind.
    • a2) In bad circumstances, you have a file for reading, and add later one for writing, but your exception (FileNotFoundException) was written only with the first in mind. A lean scope around the problematic places will help you, identifying further problems.
  • b) Don't catch basic Exception for completeness or to avoid multiple catch blocks. If you want to write to a file, many things can go wrong: Missing permission, illegal file name, no space left on device, ... . If you present the user a generic Message ("Couldn't write file " + name), he doesn't know what to do. Be as specific as possible, and you can inform him, "Only 20 MB left on device " + devicename + "We need another 8 MB (28 MB in total); please free some space and repeat or choose a different device!"). If you catch "Exception", chances are high, that you're thinking of some exception, but another one occurs, and isn't handled correctly, because the catch-block wasn't written with that possibility in mind. The best chance to find this exception is, to let it pop up, or, to log it, if the logs are controlled on a regular basis.

It can be a difference between developing an application, which is simply used by end users, or by developing an API, which is used by other developers. In an API, you often want to wrap an exception into an own exception, to make it easier for users of your api to handle it, and if you have an uniform way to handle exceptions. If your code can throw many exceptions, and would lead to ugly client code, where your customer would need to specify a bunch of exceptions over and over again, you often wrap the exceptions and rethrow them:

try  {
...
}
catch {FileNotFoundException fnfe}
{
    throw new MyApiException (fnfe);
}
catch {PermissionDeniedException pde}
{
    throw new MyApiException (pde);
}
catch {IOException  ioe}
{
    throw new MyApiException (ioe);
}

That way, your client can decide, how to handle the exception, and will find the specific type of exception, if interested, inside your exception.

As Landei points out, in Java 7 there will be a simplified technique, to catch multiple exceptions, but not only such with a common superclass, see this link here

Wrap the code at the point where you really can handle the exception, and where you can handle the error. If you can't handle the error in the function, then do no wrap the code in try/catch block.

I don't know for java, but in c++ you should catch by const reference :

try
{
  // code that can throw an exception
}
catch ( const SomeExceptionType & error )
{
  // handle the error
}

C++ isn't Java or C# or... where you need catch (or finally ) clauses to clean up after yourself. In C++, RAII does that. Consequently, I rarely ever write try / catch statements in C++, to the point where I consider it a code smell.

So, rather than contemplating which style of code you should use in conjunction with try / catch , you should ask yourself whether you need that try / catch at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM