Exception Handling Frequency/Log Detail
- by Cyborgx37
I am working on a fairly complex .NET application that interacts with another application. Many single-line statements are possible culprits for throwing an Exception and there is often nothing I can do to check the state before executing them to prevent these Exceptions.
The question is, based on best practices and seasoned experience, how frequently should I lace my code with try/catch blocks? I've listed three examples below, but I'm open to any advice.
I'm really hoping to get some pros/cons of various approaches. I can certainly come up with some of my own (greater log granularity for the O-C approach, better performance for the Monolithic approach), so I'm looking for experience over opinion.
EDIT: I should add that this application is a batch program. The only "recovery" necessary in most cases is to log the error, clean up gracefully, and quit. So this could be seen to be as much a question of log granularity as exception handling. In my mind's eye I can imagine good reasons for both, so I'm looking for some general advice to help me find an appropriate balance.
Monolitich Approach
class Program{
public static void Main(){
try{
Step1();
Step2();
Step3();
} catch (Exception e) {
Log(e);
} finally {
CleanUp();
}
}
public static void Step1(){
ExternalApp.Dangerous1();
ExternalApp.Dangerous2();
}
public static void Step2(){
ExternalApp.Dangerous3();
ExternalApp.Dangerous4();
}
public static void Step3(){
ExternalApp.Dangerous5();
ExternalApp.Dangerous6();
}
}
Delegated Approach
class Program{
public static void Main(){
try{
Step1();
Step2();
Step3();
} finally {
CleanUp();
}
}
public static void Step1(){
try{
ExternalApp.Dangerous1();
ExternalApp.Dangerous2();
} catch (Exception e) {
Log(e);
throw;
}
}
public static void Step2(){
try{
ExternalApp.Dangerous3();
ExternalApp.Dangerous4();
} catch (Exception e) {
Log(e);
throw;
}
}
public static void Step3(){
try{
ExternalApp.Dangerous5();
ExternalApp.Dangerous6();
} catch (Exception e) {
Log(e);
throw;
}
}
}
Obsessive-Compulsive Approach
class Program{
public static void Main(){
try{
Step1();
Step2();
Step3();
} finally {
CleanUp();
}
}
public static void Step1(){
try{
ExternalApp.Dangerous1();
} catch (Exception e) {
Log(e);
throw;
}
try{
ExternalApp.Dangerous2();
} catch (Exception e) {
Log(e);
throw;
}
}
public static void Step2(){
try{
ExternalApp.Dangerous3();
} catch (Exception e) {
Log(e);
throw;
}
try{
ExternalApp.Dangerous4();
} catch (Exception e) {
Log(e);
throw;
}
}
public static void Step3(){
try{
ExternalApp.Dangerous5();
} catch (Exception e) {
Log(e);
throw;
}
try{
ExternalApp.Dangerous6();
} catch (Exception e) {
Log(e);
throw;
}
}
}
Other approaches welcomed and encouraged. Above are examples only.