0

I have a lot of classes (WCF services) that contain several function. Now I need to handle errors, but I don't want to create a block try ... catch within each function (for error handling).

How can I make try...catch in any class (or something else) so that we catch errors but did not write the same block within each method?

Imran
  • 429
  • 9
  • 23
Jakobinec
  • 63
  • 13
  • 1
    I don't think there'll be a magic answer about that, but some example code could help us seeing the exact issue. – Kilazur Oct 01 '14 at 10:30
  • Using any function that could potentially throw an exception needs a try catch if you want complete correctness, there is no alternative for that. – Hatted Rooster Oct 01 '14 at 10:31
  • So you're searching for a general exception catcher? – user28470 Oct 01 '14 at 10:32
  • 1
    Why are you trying to catch errors? Normally we try to avoid catching errors, and let high level code deal with the error. – David Heffernan Oct 01 '14 at 10:33
  • I think you are looking for [IErrorHandler](http://blogs.msdn.com/b/carlosfigueira/archive/2011/06/07/wcf-extensibility-ierrorhandler.aspx) – Oğuz Sezer Oct 01 '14 at 10:50
  • You can use a logging framework and log all your errors. Let the errors bubble up. Something like ELMAH or Log4Net. But that would mean the error screen up occassionally. – Zo Has Oct 01 '14 at 11:26

3 Answers3

2

There will always be some duplication of code but you can reduce it to one line

public static class ExceptionHandler
{
    public static void Run(Action action)
    {
        try
        {
           a();
        }
        catch(Exception e)
        {
           //Do Something with your exception here, like logging
        }
    }
}

and then just call

ExceptionHandler.Run(yourAction);

you can add overloads for functions and what not but this approach is not ideal. As you may want to catch specific exceptions in certain cases.

David Pilkington
  • 13,528
  • 3
  • 41
  • 73
0

Since you did not provide code specifically, I will write some sample code to make it more obvious. If you have this:

public class MyClass
{
     public void Method1ThatCanThrowException() 
     {
          try 
          {
              // the Method1 code that can throw exception
          }
          catch (MySpecificException ex) 
          {
              // some specific error handling
          }
     }

     public object Method2ThatCanThrowException() 
     {
          try 
          {
              // the Method2 code that can throw exception
          }
          catch (MySpecificException ex) 
          {
              // the same specific error handling
          }
     }
}

So, if you intend to have single place error handling, you can use lambda, and the help of a private method:

private T CheckAndCall<T>(Func<T> funcToCheck)
{
     try 
     {
         return funcToCheck();
     }
     catch (MySpecificException ex) 
     {
         // the old specific error handling
     }
}

Notice the use of the Func<T> delegate. This is because you may need to wrap the try-catch logic around some code that can return a value.

Then you can rewrite the above methods like this:

public void Method1ThatCanThrowException() 
{
    CheckAndCall(
        () => 
        {
            // the Method1 code that can throw exception
            return null;
        });
}

public object Method2ThatCanThrowException() 
{
    return CheckAndCall(
        () => 
        {
            // the Method2 code that can throw exception
            return someObject;
        });
}
Ivaylo Slavov
  • 8,839
  • 12
  • 65
  • 108
0

For example, rather than having to do this:

public class Program
{
    public static string ReadFile(string filename)
    {
        //A BCL method that throws various exceptions
        return System.IO.File.ReadAllText(filename);
    }

    public static void Main(string[] args)
    {
        try
        {
            Console.Write(ReadFile("name.txt"));
        }
        catch (Exception e)
        {
            Console.WriteLine("An error occured when retrieving the name! {0}", e.Message);
        }

        try
        {
            Console.Write(ReadFile("age.txt"));
        }
        catch (Exception e)
        {
            Console.WriteLine("An error occured when retrieving the age! {0}", e.Message);
        }
    }
}

You could implement a "Try..." method, using the ref or out keyword as appropriate:

public class Program
{
    public static bool TryReadFile(string filename, out string val)
    {
        try 
        {
            val = System.IO.File.ReadAllText(filename);
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }

    public static void Main(string[] args)
    {
        string name, age;

        Console.WriteLine(TryReadFile("name.txt", out name) ? name : "An error occured when retrieving the name!");

        Console.WriteLine(TryReadFile("age.txt", out age) ? age: "An error occured when retrieving the age!");
    }
}

The downside to this approach is that you can't act upon a specific exception, but in the case of simply determining if an operation has or has not succeeded, I find this to be a syntactically clean approach.

James Wright
  • 3,000
  • 1
  • 18
  • 27