'When to use and when to not use try catch, throw BRE in case of best practices [closed]

I am bit confused going through banch of articles describing best practices when to use or when to not use trycatch. Nevertheless I feel like it's not clear to me enough. The problem with all those articles is that among them we can find different thoughts about the topic. Is there any really good article that may describe this topic with some examples when to use/not use trycatch? Just as example some people claims business rules exceptions are fine, but some of them saying that it's and we should avoid them to use, nevertheless I haven't found any info so when really I can use BRE as best practice. Other example is some a people claims that functions should return state like true/false which could be used for other functions to either continue or stop processing, nevertheless I found it even very messy in code to use such approach rather just throwing exception I used to use before. I would like to really see what are those best practices in 2022. Any hints, real life scenarios are welcome.

For admins: I do not agree its opinion based because there are best practices which I am referring to. Please reopen.



Solution 1:[1]

Anytime you are dealing with a piece of code that throws an exception, if that code throws an exception, and if you do not catch that exception, then your program will immediately crash or in other words (in other programing languages) the current thread will panic. An exception is more expensive than the error pattern (which I will explain shortly) mainly due to the fact that it carries a lot of data such as the StackTrace. However, the error pattern will not panic the current thread or better said in C# realm, it will not lead to a crash. It is a lighter approach to pinpoint errors only.

Now to answer your question, there are a few different approaches to exception handling.

  1. Centralized Exception Handling
  2. Interceptive Exception Handling (through proxies)
  3. Just using try-catch everywhere

There might be other creative ways to handle exceptions but they may not fit in the context of this answer.

A centralized approach has certain advantages which are:

  1. Cleaner code and no ugly try-catch blocks everywhere
  2. No nested try catch blocks
  3. Centralized exception logging system

but the disadvantage is simply, how to implement a plan b when an exception occurs? since it is a central and accordingly general approach. This is for example good in the case of a Web Application.

Interceptive exception handling, for example handling first chance exceptions, is another method which is not very efficient and it may be costly due to the proxy that sits between the actual code and an interceptor.

Using simply try-catch is of course useful when you need to introduce a plan b or plan c when an exception occurs. For example to implement a retry pattern.

However, nobody can stick to only one pattern and you have to use each method when necessary or mix all of them together in order to come up with a better design.

Finally, if an error is unrecoverable in the context of its purpose, you have to throw an exception. For example, if you cannot read file because it does not exists. On the other hand if an error is due to transient faults that can be recovered without ad-hoc procedures, you can stick with the error pattern.

Solution 2:[2]

Two totally different questions here

  • when should my code throw exceptions
  • when should I have try catches

Throw exceptions when you encounter something unexpected. DO not use then as:

  • fancy breaks

like this

 try{
  for(....){
     while(){
       throw new Exception("break");     
     }
 }
 catch{
 } 
  • fancy ways of returning info

like this

 void Froodle(){
     int res = Twang(42);
     throw new FroodleException(res);
 }
 ...
 try{
     Froodle();
 } 
 catch(FroodleException e){
     AfterFroodle(e.Twang())
}
  • or other 'fancy' , 'clever' things.

There are marginal things. For instance a function that ensure the a piece of user input in valid.

 bool IsValidZipCode(string zipStr){
      if (!regex, string compare, substr db lookup)
          return false;
 }

or

 void IsValidZipCode(string zipStr){
      if (!regex, string compare, substr db lookup)
          throw new InvalidDataException();
 }

For this kind of thing I would say use the explicit return since this functions task is the see if something is valid (same with File.Exists, etc)

If we had a function like this tho

 void SwitchZip(string zip,....){
       if(!(regex, compare .....) // valid zip?
           throw new InvalidDataException("invalid zip");
 }

rather than having a return value indicating the error.

When to catch

  • always have a long stop to catch all exceptions that bubble up unhandled, how and where this is depends on the app - web server, desktop app etc

  • Only catch if you have something useful to do with the exception. Exception handling is meant to make you code lokk cleaner becuase it removes all the testing of return codes. But too often You see people doing useless try / catch at every level.

Like this

 try{
      Wang();
  }
  catch(Exception e){
       Log("wang error");
       throw;
  } 

or even worse

  try{
      Wang();
  }
  catch(Exception e){
       Log("wang error");
  } 

Relax and let the exceptions you cannot explicitly deal with pass up the stack

ie embrace the logic of exceptions and just go

 Wang();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 pm100