user415789
user415789

Reputation:

Problem with too many try catch

Is it possible to write a method like outType? TryDo(func, out exception, params) that call func(arg1,arg2,arg3,...) which params contains arg1,arg2,arg3,... and then it return func return value and if any exception occurred return null and set the exception?

Can this be done better by another function signature?

for example I have string Foo1(int i) { return i.ToString()}

void Foo2(int[] a) {throw new Exception();}

and then call

string t = TryDo(Foo1, out ex, {i});

TryDo(Foo2, out ex, {});

-----------Edited------------------

        string t;
        SomeClass c;
        try
        {
            t = Foo1(4, 2, new OtherClass());
        }
        catch (Exception ex)
        {
            Log(ex);
            if (/*ex has some features*/)
                throw ex;
        }

        try
        {
            Foo2();
        }
        catch (Exception ex)
        {
            Log(ex);
            if (/*ex has some features*/)
                throw ex;
        }
        .
        .
        .

I want to make it like this.

        string t = TryDo(Foo1, out ex, {4, 2, new OtherClass());
        Examine(ex);
        SomeClass c = TryDo(Foo2, out ex, {});
        Examine(ex);

Upvotes: 0

Views: 2521

Answers (5)

Martin Liversage
Martin Liversage

Reputation: 106796

I would avoid using out parameters unless absolutely necessary.

Here is a quote from the Design Guidelines for Developing Framework Libraries:

Avoid using out or reference parameters.

Working with members that define out or reference parameters requires that the developer understand pointers, subtle differences between value types and reference types, and initialization differences between out and reference parameters.

You can instead create a return type that wraps the result of your call:

class CallResult<T> where T : class {
  public CallResult(T result) { Result = result; }
  public CallResult(Exception exception) { Exception = exception; }
  public T Result { get; private set; }
  public Exception Exception { get; private set; }
  public Boolean IsSuccessful { get { return Exception == null; } }
}

Your method could then be implemented like this:

CallResult<T> TryDo<T>(Func<Object[], T> action, params Object[] args) where T : class {
  try {
    return new CallResult<T>(action(args));
  }
  catch (Exception ex) {
    return new CallResult<T>(ex);
  }
}

You can call it like this:

var callResult = TryDo<String>(Foo1, 4, 2, new OtherClass());
if (!callResult.IsSuccessful)
  Examine(callResult.Exception);

However, if you intend to rethrow the exception in the Examine method loosing the stacktrace you should really reconsider your approach.

Upvotes: 2

Massimiliano Peluso
Massimiliano Peluso

Reputation: 26717

if you are having too many try...catch(I can't understand why) you could go for AOP to centralize the Exception handling.

Below you can find a link that explains how to use it:

http://www.codeproject.com/KB/architecture/ExceptionHandlingWithAOP.aspx

Upvotes: 0

jgauffin
jgauffin

Reputation: 101130

What you are asking indicates that you have misunderstood how exceptions should be handled. Using try/catch everywhere can produce undesired results and make your application a whole lot harder to debug.

In short, only handle exceptions in the following cases:

  1. You can handle the exception and return promised result
  2. Catch layer specific exceptions and replace them with more generic exceptions (SqlException -> DataSourceException)
  3. Catch all is OK in the top layer
  4. Catch all is OK in threads (since uncaught exceptions in threads will crash your app)

More info in my blog: http://blog.gauffin.org/2010/11/do-not-catch-that-exception/

Update

PLEASE do not use throw ex. You are destroying the original call stack and therefore hiding where the exception was thrown originally. throw; is your puppy. Use it everywhere and all the time.

Upvotes: 4

alex
alex

Reputation: 1278

Yes it is, but why would you want that?

int? TryDo(delegate d, out Exception e, params object[] par)  
{
   try
   {
      int res = d.Invoke(par);
      e = null;
      return res;
   }  
   catch(Exception ex) { e = ex; return null; }
}

Upvotes: 0

26071986
26071986

Reputation: 2330

Yes, it's possible.

But why would you like to return a possible exception this way? You could throw further and process at the needed place.

Upvotes: 2

Related Questions