3

I have exception handling code in every method for the below code for the bottom level methods

throw new Exception("The error that happens");

Is there any way I can avoid writing this code again and again in each method?

I am trying to write my own code and not using any log frameworks

private void TopLevelMethod()
{
    try
    {
        SomeMethod();
    }
    catch (Exception ex)
    {
        // Log/report exception/display to user etc.
    }
}

private void SomeMethod()
{
    TestPartA();
    TestPartB();
    TestPartC();
    TestPartD();
}

private void TestPartA()
{
    // Do some testing...
    try
    {
        if (somethingBadHappens)
        {
            throw new Exception("The error that happens");
        }
    }
    catch (Exception)
    {
        // Cleanup here. If no cleanup is possible, 
        // do not catch the exception here, i.e., 
        // try...catch would not be necessary in this method.

        // Re-throw the original exception.
        throw;
    }
}

private void TestPartB()
{
    // No need for try...catch because we can't do any cleanup for this method.
    if (somethingshappens)
    {
        throw new Exception("The error that happens");
    }
}
farid bekran
  • 2,684
  • 2
  • 16
  • 29
priya
  • 33
  • 1
  • 3
  • do you know the difference between `throw & throw new` take a look here as well as do some googling http://stackoverflow.com/questions/2999298/difference-between-throw-and-throw-new-exception – MethodMan Jun 25 '15 at 20:38
  • Thankyou .I know about it.I am trying to look some good design patterns for exception management with any centralized manager. – priya Jun 25 '15 at 20:50
  • create your own custom class that handles exceptions etc.. for the app this is rather opinionated in nature in regards to some good design patterns but that's just my opinion.. – MethodMan Jun 25 '15 at 21:00
  • Just an opinion: rather than throwing exceptions in methods, build functions returning a bool (success or failure) and updating an error string or an error container (e.g. List). You will see the benefits of this approach in debug mode that will only break on unexpected exceptions. – Graffito Jun 25 '15 at 21:12
  • Graggito: Would you please give sample code example.Thankyou.... – priya Jun 25 '15 at 21:15
  • What kind of presentation layer are you using? For example, ASP.Net MVC, Web Form, WPF or Win Form. – Win Jun 25 '15 at 21:59
  • Your question is both, too broad and opinion based. But one thing remains true regardless - your exception handling will depend on your overall application design. – T.S. Jun 25 '15 at 22:28

3 Answers3

3

Only catch errors if you want to do something meaningful to them such as:

  1. Wrapping the exception with a framework exception (e.g. SqlException. ADO.NET never passes you socket-level errors. It passes you a meaningful SQL error code)
  2. Cleanup
  3. Actually responding (e.g. retry, or insert default values)

Logging is almost never appropriate. The top level handler should log. Certainly not every method in the path should log. What a clutter for logs and for the code. Don't do that.

Simply don't swallow error information and let the error bubble out. That way there is no reason left to insert local logging code for errors everywhere.

usr
  • 168,620
  • 35
  • 240
  • 369
1

If you prefer using Functional Programming like code style one way is to use callback error callbacks. Example :

    private void SomeMethod()
    {
        // do something
    }
     public bool Execute(Action act, Action<Exception> onErrorCallback)
        {
            var res = true;
            try
            {
                act();
            }
            catch (Exception ex)
            {
                res = false;
                onErrorCallback(ex);
            }
            return res;
        }

And use Execute like this:

   var successfull = true;
   successfull &= Execute(SomeMethod, (ex) => {  /* clean up */ });
   successfull &= Execute(SomeMethod, (ex) => {  /* clean up */ });
   successfull &= Execute(SomeMethod, (ex) => {  /* clean up */ });
   successfull &= Execute(SomeMethod, (ex) => {  /* clean up */ });
   if (!successfull)
       ; // show user or something else
farid bekran
  • 2,684
  • 2
  • 16
  • 29
0

Graffito: Would you please give sample code example.Thankyou...

Your code refactored:

private void TopLevelMethod()
{ 
    List<string> errors=new List<string>() ;
    if (!SomeMethod(errors)) { /* Log/report errors/display to user etc. */ }
}

private bool SomeMethod(List<string> errors)
{
    return TestPartA(errors) && TestPartB(errors) && TestPartC(errors) && TestPartD(errors);
}

private bool TestPartA(List<string> errors)
{
  bool result = true ;
  try 
  {
    // Do some testing...
    if (somethingBadHappens) { result=false; errors.Add("The error that happens"); }
  }
  catch (Exception ex) { errors.Add("Error in TestPartA: "+Ex.Exception.Message.ToString()) ; }
  return result ;
}

private bool TestPartB(List<string> errors)
{
  bool result = true ;
  // Do some testing...
  if (somethingBadHappens) { result = false ; errors.Add("The error that happens"); }
  return result ;
}
Graffito
  • 1,658
  • 1
  • 11
  • 10
  • 1
    Converting exception to return values loses the benefits that exceptions bring. Further, all methods in this code snippet depend on and mutate shared state (the list) which is another drawback. I would fail this in a code review. – usr Jun 25 '15 at 23:11
  • **usr** said "_Converting exception to return values loses the benefits that exceptions bring_". For many exceptions, return values are appropriate (for example, a failure to write on a file). Some exceptions should be kept (e.g. detection of abnormal data provided by a previous procedure). Note also that exceptions processing is slow. For example, benchmark "b=int.tryParse(s,out i) vs "try { i=int.Parse(s) ; } catch {}". – Graffito Jun 25 '15 at 23:43