How do I write a function that will call another function and catch some exceptions?

I have a number of functions with different argument signatures:

public void function1 (string s1, string s1, string s3, string s4) {...}
public void function2 (int i1, int i2, string s3, string s4) {...}    
public void function3 (int i1, string s2, int i3, string s4) {...}
.
.
etc //some 30 odd functions

      

calling each function can throw a bunch of exceptions like TimeoutException, CommunicationException, etc. (yes these are WCF proxy features)

Now I need to wrap these calls in try catch blocks, but the DRY principle says I am doing it wrong by writing so many of the same catch catch blocks:

public void Interfacefunction1 (...) {
    try {
        function1 (...);
    }
    catch (TimeoutException) {
        taskResult.Success = false;
        taskResult.Message = Resources.ServerConnectionBroke;
    }            
    catch (CommunicationException) {
        taskResult.Success = false;
        taskResult.Message = Resources.CommunicationFailed;
    }
}

//and...

public void Interfacefunction2 (...) {
    try {
        function2 (...);
    }
    catch (TimeoutException) {
        taskResult.Success = false;
        taskResult.Message = Resources.ServerConnectionBroke;
    }            
    catch (CommunicationException) {
        taskResult.Success = false;
        taskResult.Message = Resources.CommunicationFailed;
    }
}
//etc

      

Is there a way to write a single function that will call these functions and catch exceptions if thrown?

EDIT:

I have no control over the sequence of the interface functions in which they will be called. All these functions are available to the user (another programmer), who will call any, two or many in any sequence that she likes. I just need to report success and an error message in case of failure for EACH operation. (see updated code snippet).

+2


source to share


5 answers


You can use lambdas:

CatchCommonExceptions(() => function1(...));

private void CatchCommonExceptions(Action action)
{
    try
    {
        action ();
    }
    catch (TimeoutException) {
        taskResult.Success = false;
        taskResult.Message = Resources.ServerConnectionBroke;
    }
    catch (CommunicationException)
    {
        taskResult.Success = false;
        taskResult.Message = Resources.CommunicationFailed;
    }
}

      



And you can have Func <T> overloads for those that return values.

EDIT: You can view the full source here .

+8


source


What happens after you catch the exception? Can you refactor it? Often you can, in theory, take try catch to another level.

 processUserRequest() {

     try {
           if (function1() )
               function2()

           function3()
           ... etc

           prepare success response to user

     } catch (TimeOutException ) {
           log message
           prepare fail response to user
     } catch ... etc 

     }

     send response

}

      

Also is it possible to reduce the number of exceptions you need to catch? In Java, I use an exception hierarchy. I have a TransientException that is thrown when it is reasonable to expect the same request to be repeated. Timeout and communication exceptions are subclasses of TransientException, so I only need to catch the TransientrException. Likewise, I have an InvalidRequestException - you can make an invalid request as many times as you want, but it will never work! So I can subclass InvalidRequestException for cases like invalid SQL.

In response to your further explanation:

Your intent is to wrap each function so that the caller can test the success code rather than catch an exception. Desire is that the calling code will be code

Response result = function1( ... ) ;
if ( result.isError() ) {
    do something with result.reason();
} else {
    maybe do something with the answer
}

      

Let me first tell you why bother? They can catch all Exceptions with one block.



try { 
    function1( ... )
    maybe do somethign with the annswer
}
catch(Exception e) {
    callExceptionReporter(e);
}

      

it is in my eyes much clearer, the control flow is clear. It's no more than lines of code and is much easier to maintain. There seems to be a general consensus that exceptions make the code incomprehensible - I just disagree.

NOTE: The idea of ​​"Catch an Exception" has caused some controversy. Let me clarify a couple of points.

  • Catching an Exception is not evil in itself, but it is very important that if you catch an Exception, you are doing the right thing. The questions are discussed in this question .

  • I am not a supporter of silence, swallowing any exception, and least of all important systemic exceptions. For every exception caught one has to decide whether to log a message, often logging is the minimum thing to do. In this case, we are catching the exception so that we can account for general handling. This is not a common thing, but catching that Exception is not inherently wrong if we do the right thing. Don't blindly follow rules such as "don't catch an Exception".

  • The callExceptionReporter () implementation is responsible for correct execution. Application-specific exceptions can prepare the error result. With other exceptions, he can simply defy.

  • Some exceptions are not exciting. The example from the .NET 2.0 StackOverflowException is not (usually) exciting. It doesn't make any difference to our code, we won't catch it, we don't want to catch it.

  • There have been suggestions that by catching an Exception, we can open up some opportunity to permanently block the wrong behavior. This is simply not the case. Finally blocks the fire long before our Exception handler is reached. If, finally, they misbehave, it is not related to the use of this catch. If we hit that catch because the block eventually threw an exception, regardless of its just another exception to process or retron.

Going back to the original question If you want / need to go further with your plan, then, as noted, factor the Exception handling into your own function. Then you write minimal repetitive code.

try { 
    return function1( ... )
}
catch(Exception e) {
    return prepareExceptionResponse(e);
}

      

As long as you do the right thing in prepareExceptionResponse () by reworking exceptions at a low level, you do no harm. This is unusual for Cathc Exception at this level, but you have a special need to do general exception handling.

+4


source


You will need to call every function and throw an exception every time. But you can make your code easier to clean if you use something like exception handling block in Enterprise Library . This way, you can configure the policy for WCF call failed and do not have to handle each different type of exception separately.

+1


source


Haven't tested it myself, but I just came up with the following:

try {
function1 (...);

}
catch (Exception ex) {
    //this will not catch all the exception types even though it may look like :)
    HandlingWCFExceptions(ex, taskResult);
}
....
private void HandlingWCFExceptions(Exception ex, TaskResult result)
{
    try {
        //This will preserve the original exception status including call stack
        throw;
    } 
    catch (TimeoutException) {
    taskResult.Success = false;
    taskResult.Message = Resources.ServerConnectionBroke;
    }         
    catch (CommunicationException) {
        taskResult.Success = false;
        taskResult.Message = Resources.CommunicationFailed;
    }
    //catch other (WCF) exception types that you can handle safely
    //Any other exception not caught here will bubble up
    ...
}

      

This one will work well with anyone funtionN()

with different arguments and return types, especially if you don't have any control over the WCF services.

0


source


You have a class that handles all possible exceptions that your application might throw. Dump the method from this class that will handle the exception. A method can take the type of the exception, where it was thrown, etc., and handle them accordingly.

In the series of methods that you have, just call a method in your exception handling class.

-1


source







All Articles