I've written an extension method for use with WCF services that keeps all the disposal and exception handling logic in one place. The method is as follows:
public static TResult CallMethod<TChannel, TResult>(
this ClientBase<TChannel> proxy,
Func<TResult> func) where TChannel : class
{
proxy.ThrowIfNull("proxy");
func.ThrowIfNull("func");
try
{
// set client credentials
return func();
}
finally
{
if (proxy != null)
{
try
{
if (proxy.State != CommunicationState.Faulted)
{
proxy.Close();
}
else
{
proxy.Abort();
}
}
catch (CommunicationException)
{
proxy.Abort();
}
catch (TimeoutException)
{
proxy.Abort();
}
catch (Exception)
{
proxy.Abort();
throw;
}
}
}
}
The method will be used like this:
public int CreateBusinessObject(BusinessObject item)
{
MyServiceClient proxy = new MyServiceClient();
return proxy.CallMethod(() => proxy.CreateBusinessObject(item));
}
My question really is whether this would be better as a static method which creates the service proxy? I'm slightly worried about my current implementation. Should the construction of the proxy be inside the try/catch? My current understanding is that if the constructor fails, there is nothing to dispose of anyway.
If the constructor fails, the entire object is in an invalid state. You should not be worried about disposing in this case.
A nice test for this is what would happen when you execute the following:
class Program
{
static void Main(string[] args)
{
using (new TestClass())
{
Console.WriteLine("In using");
}
}
class TestClass : IDisposable
{
public TestClass()
{
throw new Exception();
}
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
}
The result is that the Disposing never gets reached. This is what happens when the constructor fails.
Related
Simplified, i have these 2 Extension method:
public static class Extensions
{
public static string GetString(this Exception e)
{
return "Standard!!!";
}
public static string GetString(this TimeoutException e)
{
return "TimeOut!!!";
}
}
And here is where i use them:
try
{
throw new TimeoutException();
}
catch (Exception e)
{
Type t = e.GetType(); //At debugging this a TimeoutException
Console.WriteLine(e.GetString()); //Prints: Standard
}
I have more GetString() extensions.
My try{...}catch{...} is getting large and basically i search for ways to shorten it down to 1 catch that calls the extension based on the type of the exception.
Is there a way to call the right extension method at runtime?
As Yacoub Massad suggests you can use dynamic, because with dynamic method overload resolution is deferred at runtime through late binding.:
public static class Extensions
{
public static string GetString<T>(this T e) where T : Exception
{
// dynamic method overload resolution is deferred at runtime through late binding.
return GetStringCore((dynamic)e);
}
static string GetStringCore(Exception e)
{
return "Standard!!!";
}
static string GetStringCore(TimeoutException e)
{
return "TimeOut!!!";
}
static string GetStringCore(InvalidOperationException e)
{
return "Invalid!!!";
}
}
This should make the trick.
Extension methods are the wrong tool here.
I would foster the use of polymorphism to solve your problem:
public abstract class BaseException : Exception
{
public abstract string GetString();
}
public sealed class TimeoutException : BaseException
{
public override string GetString() => "TimeOut!!!";
}
public sealed class MyException : BaseException
{
public override string GetString() => "Standard!!!";
}
Usage
try
{
throw new TimeoutException(); //or whatever BaseException's children
}
catch (BaseException e)
{
//here I'm assuming you know that you are swallowing the exception (which may be an anti-pattern)
Console.WriteLine(e.GetString());
}
Edit
It looks like you have not the full control over which and when exceptions are thrown. Another possibility would be to add 1 catch clause for each behavior (rather than for each exception type) and get rid of GetString():
try
{
throw new TimeoutException();
}
catch (Exception e) when (e is ArgumentNullException || e is FormatException)
{
//do something
}
catch (Exception e) when (e is TimeoutException)
{
//do something
}
catch (Exception e)
{
throw new NotImplementedException($"Hey Mike, write something for {e.GetType()}, will ya?"); //idea from Jeroen
}
I'm trying to make something like base "exception handler" thing. So this base class will try-catch exceptions when any method (with any number of parameters) in derived class gets invoked. I'm not good in describing this with words, so here is the scenario:
public abstract BaseClass
{
Exception _ex;
public Exception LastKnownException
{
get
{
return this._ex;
}
}
//...
//what do I do here to assign the value of above property when some random exception occur in derived class?
//...
//The closest I can get...
public void RunMethod(Action method)
{
try
{
method.Invoke();
}
catch (Exception ex)
{
this._ex = ex;
}
}
}
public class DerivedClass : BaseClass
{
public void DoRandomMethod(int couldBeOfAnyTypeHere, bool andIndefiniteNumberOfThese)
{
bool result = false;
var someObject = new OtherClass(couldBeOfAnyTypeHere, out andIndefiniteNumberOfThese);
someObject.DoInternalWork(result); // <-- here is where I need the base class to take care if any exception should occur
}
public int AnotherMethod(int? id)
{
if (!id.HasValue)
id = Convert.ToInt32(Session["client_id"]);
var someOtherObject = new OtherClassB(id.Value);
return someOtherObject.CheckSomething(); // <-- and catch possible exceptions for this one too
}
//The closest I can get... (see base class implementation)
public List<RandomClass> GetSomeListBy(int id)
{
RunMethod(() =>
string[] whateverArgs = new[] { "is", "this", "even", "possible?" };
YetAnotherStaticClass.GetInstance().ExecuteErrorProneMethod(whateverArgs); // <-- Then when something breaks here, the LastKnownException will have something
);
}
}
public class TransactionController : Controller
{
public ActionResult ShowSomething()
{
var dc = new DerivedClass();
dc.DoRandomMethod(30, true);
if (dc.LastKnownException != null)
{
//optionally do something here
return RedirectToAction("BadRequest", "Error", new { ex = dc.LastKnownException });
}
else
{
return View();
}
}
}
EDIT: My simple approach will work, only, I don't want to have to wrap all methods with this lambda-driven RunMethod() method all the time -- I need the base class to somehow intercept any incoming exception and return the Exception object to the derived class without throwing the error.
Any ideas would be greatly appreciated. And thanks in advance!
I think you should consider using the event System.AppDomain.UnhandledException
This event will be raised whenever an exception occurs that is not handled.
As you don't clutter your code with the possibilities of exception, your code will be much better readable. Besides it would give derived classes the opportunity to catch exceptions if they expect ones, without interfering with your automatic exception catcher.
Your design is such, that if someone calls several functions of your derived class and then checks if there are any exceptions the caller wouldn't know which function caused the exception. I assume that your caller is not really interested in which function causes the exception. This is usually the case if you only want to log exception until someone investigates them.
If that is the case consider doing something like the following:
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
if (ex != null)
logger.LogException(ex);
// TODO: decide whether to continue or exit.
}
If you really want to do this only for your abstract base class
public abstract BaseClass
{
private List<Exception> unhandledExceptions = new List<Exception>();
protected BaseClass()
{
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
}
private void UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
if (ex != null)
this.UnhandledExceptions.Add(ex);
}
public List<Exception> LastKnownExceptions
{
get { return this.unhandledExceptions; }
}
I had a similar requirement for catching exceptions, but used a specific implementation (i.e. not an abstract class) to encapsulate the handling of errors.
Please note this takes in an argument for any expected exceptions (params Type[] catchableExceptionTypes), but of course you can modify to suit your own requirements.
public class ExceptionHandler
{
// exposes the last caught exception
public Exception CaughtException { get; private set; }
// allows a quick check to see if an exception was caught
// e.g. if (ExceptionHandler.HasCaughtException) {... do something...}
public bool HasCaughtException { get; private set; }
// perform an action and catch any expected exceptions
public void TryAction(Action action, params Type[] catchableExceptionTypes)
{
Reset();
try
{
action();
}
catch (Exception exception)
{
if (ExceptionIsCatchable(exception, catchableExceptionTypes))
{
return;
}
throw;
}
}
// perform a function and catch any expected exceptions
// if an exception is caught, this returns null
public T TryFunction<T>(Func<T> function, params Type[] catchableExceptionTypes) where T : class
{
Reset();
try
{
return function();
}
catch (Exception exception)
{
if (ExceptionIsCatchable(exception, catchableExceptionTypes))
{
return null;
}
throw;
}
}
bool ExceptionIsCatchable(Exception caughtException, params Type[] catchableExceptionTypes)
{
for (var i = 0; i < catchableExceptionTypes.Length; i++)
{
var catchableExceptionType = catchableExceptionTypes[i];
if (!IsAssignableFrom(caughtException, catchableExceptionType)) continue;
CaughtException = caughtException;
HasCaughtException = true;
return true;
}
return false;
}
static bool IsAssignableFrom(Exception exception, Type type)
{
if (exception.GetType() == type) return true;
var baseType = exception.GetType().BaseType;
while (baseType != null)
{
if (baseType == type) return true;
baseType = baseType.BaseType;
}
return false;
}
void Reset()
{
CaughtException = null;
HasCaughtException = false;
}
}
I have a class which exposes some functionality,
and I want to ensure exceptions will be handled by a custom ErrorHandler class.
Currently I can achieve this by a try / catch statement per each method, and process the exception by the error handler there.
My question is if there is a better way / design pattern to do it.
Code:
public class BasicErrorHandler
{
public void ProcessException(Exception ex)
{
//Does error handling stuff
}
}
public class Manager
{
BasicErrorHandler _errorHandler;
public Manager()
{
_errorHandler = new BasicErrorHandler();
}
public void MethodA()
{
try
{
//Does Something
}
catch(Exception ex)
{
_errorHandler.ProcessException(ex);
}
}
public void MethodB()
{
try
{
//Does Something Else
}
catch(Exception ex)
{
_errorHandler.ProcessException(ex);
}
}
}
In keeping with DRY principles, you could just wrap your try...catch logic into into own method which takes a predicate of the actual work to do:
public class Manager
{
BasicErrorHandler _errorHandler;
public Manager()
{
_errorHandler = new BasicErrorHandler();
}
public void MethodA()
{
DoWork( () => {
// do something interesting here
});
}
public void MethodB()
{
DoWork( () => {
// do something else interesting here
});
}
private void DoWork(Action action)
{
try
{
action();
}
catch(Exception ex)
{
_errorHandler.ProcessException(ex);
}
}
}
I've crafted this quickly and without thinking too much in the implications, but if you want to avoid all the try/catch blocks, you could do something like:
public class BasicErrorHandler
{
public void ProcessException(Exception ex)
{
//Does error handling stuff
}
public void Do(Action act)
{
try
{
act();
}
catch(Exception ex)
{
ProcessException(ex);
}
}
}
And then use it like:
public class Manager
{
BasicErrorHandler _errorHandler;
public Manager()
{
_errorHandler = new BasicErrorHandler();
}
public void MethodA()
{
_errorHandler.Do(() => {
//Does Something
});
}
public void MethodB()
{
_errorHandler.Do(() => {
//Does Something Else
});
}
}
Design patterns are there to solve a problem. Which problem are you trying to solve? What is wrong with the Try Catch blocks?
Only thing I can imagine is you want to have more clean code. Some answers suggest a helper method with an action. Given the helper methods that encapsulate a delegate: Do consider the impact on your stack trace and debugging sessions using these delegates. It might make logging etc more hard to understand.
If your intend is to do separation of concern, I would say If you can't handle it, just don't catch the exception. Let the class invoking the method handle it. If you insist to have a handler in your class, I would suggest Inversion of Control. That way, your class is not in control of determining which class should handle its exceptions.
Rx .net is for You. Advanced error handling gives You the ability to highly customize Your error handling. Check out the pages about that.
For example:
var source = new Subject<int>();
var result = source.Catch<int, TimeoutException>(tx=>Observable.Return(-1));
result.Dump("Catch");
source.OnNext(1);
source.OnNext(2);
source.OnError(new ArgumentException("Fail!"));
You'll get the following output:
Catch-->1
Catch-->2
Catch failed-->Fail!
The number of retries, the handling of how much time a method can take, everything can be configured.
The following is an Aspect oriented method of soling the problem, this makes use of PostSharp to do the weaving.
[Serializable]
public class HandleExceptionsAttribute : OnExceptionAspect {
/// <summary>
/// Initializes a new instance of the <see cref="HandleExceptionsAttribute"/> class.
/// </summary>
public HandleExceptionsAttribute() {
AspectPriority = 1;
}
public override void OnException(MethodExecutionArgs args) {
//Suppress the current transaction to ensure exception is not rolled back
using (var s = new TransactionScope(TransactionScopeOption.Suppress)) {
//Log exception
using (var exceptionLogContext = new ExceptionLogContext()) {
exceptionLogContext.Set<ExceptionLogEntry>().Add(new ExceptionLogEntry(args.Exception));
exceptionLogContext.SaveChanges();
}
}
}
}
[HandleExceptions]
public class YourClass {
}
I'm using the heavily-undocumented Castle dynamic-proxy system. I've managed to make it do almost everything I want, except for one thing: How do you make a proxied method throw an exception instead of returning a value?
public sealed class MyInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (CheckArgs(invocation.Arguments))
{
invocation.ReturnValue = DoRealWork(invocation.Arguments);
}
else
{
invocation.Exception = new InvalidOperationException(); // How?
}
}
}
From the point of view of the proxied object the interceptor is not visible; it simply calls its own virtual method, and DynamicProxy invokes the correct interceptor methods before returning the ReturnValue to the caller.
So if you want to throw an exception just throw it from the interceptor:
if (CheckArgs(invocation.Arguments))
{
invocation.ReturnValue = DoRealWork(invocation.Arguments);
}
else
{
throw new InvalidOperationException();
}
From the point of view of the caller it will be an exception in the called method.
Edit for comment:
Regarding the type of the exception thrown in the generator I have the correct type, not a wrapper:
public interface IDummy
{
string DoSomething();
}
public class Dummy: IDummy {
public virtual string DoSomething()
{
return string.Empty;
}
}
public class MyCustomException : Exception {}
public class CustomIntercept: IInterceptor
{
public void Intercept(IInvocation invocation)
{
throw new MyCustomException();
}
}
internal class Program
{
private static void Main(string[] args)
{
var pg = new ProxyGenerator();
GetValue(pg.CreateInterfaceProxyWithoutTarget<IDummy>(new CustomIntercept()));
GetValue(pg.CreateClassProxy<Dummy>(new CustomIntercept()));
GetValue(pg.CreateClassProxyWithTarget<Dummy>(new Dummy(), new CustomIntercept()));
GetValue(pg.CreateInterfaceProxyWithTarget<IDummy>(new Dummy(), new CustomIntercept()));
}
private static void GetValue(IDummy dummy)
{
try
{
dummy.DoSomething();
}
catch (Exception e)
{
Console.WriteLine(e.GetType().Name);
}
}
}
All four outputs are MyCustomException
Can you make sure that the TargetInvocationException doesn't come from your own code? What version of the DynamicProxy are you using (I'm using the one in Castle.Core 3.2)
I am developing a solution which will connect to a wide variety of servers to read data and perform operations. There are many variables which complicate reliable communications such as firewalls, stopped/failed services, authentication differences, and various software configurations. There are methods I can use to work around these issues, though at the time of execution it is not known which will prove successful.
My goal is to create an interface and implementations which can be used to perform operations. The first method call will be to the fastest implementation which works for the majority of devices followed by other calls which can deal with the issues listed earlier.
In a perfect world the process would be written to quickly identify which method would be successful, but in my tests that took as much processing time as simply catching an exception. While performance is always a consideration, in the end it is more important that the task completes successfully.
Below is an example I created which demonstrates a worst case scenario iterating over a list of implementations. While this works well for one method, it doesn't follow the DRY principle when used in 20 or more different operations. One possible solution is Unity and Interception but I found that the invoke method in the call handler uses a resolved implementation, not a list of possible implementations. Unless I am missing something, that doesn't appear to be an option. Also, I will need to follow this pattern for several interfaces, so it would be nice to create a generic handler which can iterate over a list of implementations.
Any advice on how to complete this task would be appreciated!
Interface
public interface IProcess
{
int ProcessItem(string workType);
}
Implementations
public class ProcessImplementation1 : IProcess
{
public int ProcessItem(string workType)
{
throw new TimeoutException("Took too long");
}
}
public class ProcessImplementation2 : IProcess
{
public int ProcessItem(string workType)
{
throw new Exception("Unexpected issue");
}
}
public class ProcessImplementation3 : IProcess
{
public int ProcessItem(string workType)
{
return 123;
}
}
Special Implementation loops through the other implementations until one succeeds without exception
public class ProcessImplementation : IProcess
{
public int ProcessItem(string workType)
{
List<IProcess> Implementations = new List<IProcess>();
Implementations.Add(new ProcessImplementation1());
Implementations.Add(new ProcessImplementation2());
Implementations.Add(new ProcessImplementation3());
int ProcessId = -1;
foreach (IProcess CurrentImplementation in Implementations)
{
Console.WriteLine("Attempt using {0} with workType '{1}'...",
CurrentImplementation.GetType().Name, workType);
try
{
ProcessId = CurrentImplementation.ProcessItem(workType);
break;
}
catch (Exception ex)
{
Console.WriteLine(" Failed: {0} - {1}.",
ex.GetType(), ex.Message);
}
Console.WriteLine();
if (ProcessId > -1)
{
Console.WriteLine(" Success: ProcessId {0}.", ProcessId);
}
else
{
Console.WriteLine("Failed!");
}
return ProcessId;
}
}
}
You could implement the processing operation as a generic extension method that you pass a method that does the processing for a single item:
public static int ProcessItems<T>(this IEnumerable<T> items, Func<T, int> processMethod)
{
foreach (var item in items)
{
try
{
return processMethod(item);
}
catch(Exception) {}
}
return -1;
}
Now you have factored out the actual type of the item and what method you use for processing. The only thing "fixed" is the result type of the generic method which is an integer.
For your current example you could call it like this then:
List<IProcess> implementations = ...;
int processResult = items.ProcessItems(x => x.ProcessItem(workType));
You could use the TryParse pattern in a second interface:
public interface IProcess
{
int ProcessItem(string workType);
}
internal interface ITryProcess
{
bool TryProcessItem(string workType, out int result);
}
public class ProcessImplementation1 : ITryProcess
{
public bool TryProcessItem(string workType, out int result)
{
result = -1;
return false;
}
}
public class ProcessImplementation : IProcess
{
public int ProcessItem(string workType)
{
var implementations = new List<ITryProcess>();
implementations.Add(new ProcessImplementation1());
// ...
int processId = -1;
foreach (ITryProcess implementation in implementations)
{
if (implementation.TryProcessItem(workType, out processId))
{
break;
}
}
if (processId < 0)
{
throw new InvalidOperationException("Unable to process.");
}
return processId;
}
}
Here's a solution similar to the one created by #BrokenGlass if you want something very simple and "generic."
public void TryAllImplementations<TService>(
IEnumerable<TService> services,
Action<TService> operation,
Action<Exception> exceptionHandler = null)
{
int dummy = 0;
TryAllImplementations(
services,
svc => { operation(svc); return dummy; },
exceptionHandler);
}
public TReturn TryAllImplementations<TService, TReturn>(
IEnumerable<TService> services,
Func<TService, TReturn> operation,
Action<Exception> exceptionHandler = null)
{
foreach (var svc in services)
{
try
{
return operation(svc);
}
catch (Exception ex)
{
if (exceptionHandler != null)
exceptionHandler(ex);
}
}
throw new ProgramException("All implementations have failed.");
}
Since I see a Unity tag, you could use ResolveAll<TService>() on your container using your service interface to get all implementations. Combining that with this code, you could do something like an extension method on IUnityContainer:
public static class UnityContainerExtensions
{
public static void TryAllImplementations<TService>(
this IUnityContainer container,
Action<TService> operation,
Action<Exception> exceptionHandler = null)
{
int dummy = 0;
container.TryAllImplementations<TService, int>(
svc => { operation(svc); return dummy; },
exceptionHandler);
}
public static TReturn TryAllImplementations<TService, TReturn>(
this IUnityContainer container,
Func<TService, TReturn> operation,
Action<Exception> exceptionHandler = null)
{
foreach (var svc in container.ResolveAll<TService>())
{
try
{
return operation(svc);
}
catch (Exception ex)
{
if (exceptionHandler != null)
exceptionHandler(ex);
}
}
throw new ProgramException("All implementations have failed.");
}
}
Here's how using it could work:
IUnityContainer container;
// ...
container.RegisterType<IProcess, ProcessImplementation1>();
container.RegisterType<IProcess, ProcessImplementation2>();
container.RegisterType<IProcess, ProcessImplementation3>();
// ...
container.TryAllImplementations(
(IProcess svc) => svc.ProcessItem(workType),
ex => Console.WriteLine(
" Failed: {0} - {1}.",
ex.GetType(),
ex.Message));