views:

62

answers:

4

Hi all,

I have a Ria service to call logic code. I want to write try catch block in every logic funtion to provide ways to handle unhandeled exceptions.

try
{
//something
}
catch(BussinessException e)
{
//save e.info to database
}

But I don't want to write this block code everywhere in my logic, and I don't want to put the exception handling piece in RIA service since another type of service also call the logic.

Does anybody have a one-place exception handling solution for me?

Thanks a lot.

+2  A: 

Based off your history I am pretty sure this is C# so here is my take.

The best way to avoid the duplication would be to wrap your logic like this.

private static void ExecuteLogic(Action action)
{
    try
    {
        action();
    }
    catch(BussinessException e)
    {
        //save e.info to database
    }
}

With this in place you can easily perform various operations that share the same error handling.

ExecuteLogic(
    () =>
    {
        // Do something...
    }
);
ChaosPandion
@ChaosPandion.. Wanted to ask some one smart.. Could you extend IDispose for something like this also. Good idea bad idea thoughts?
Kieran
+1 Otherwise known as command pattern, good solution.
Igor Zevaka
@Kieran - I am sure you could extend IDisposable in an infinite number of ways. Can you tell me what the end goal you would desire?
ChaosPandion
Great! This is convinient and also fit in our stupid static logic class.
@ChaosPandion hey dude. thx for your response. I have been looking into idisposable a bit more and it is not as suited to this as i first thought...
Kieran
A: 

If you want only to log exception, as I can see from your example, you can subscribe to AppDomain.FirstChanceException. But you wouldn't be able to handle it. Oh. btw this event was introduces only in .NET 4 :(.

Dmitry Lobanov
A: 

Here is a more conventional Object Oriented solution using Command Pattern.

public interface ICommand {
  void Execute();
}

public class BankAccountWebServiceCall: ICommand(){

  string name;
  int accountNo;

  public BankAccountWebServiceCall(string name, int accountNo) {
    this.name= param1;
    this.accountNo= accountNo;
  }

  //ICommand implementation
  public void Execute() {
    SomeWebService.Call(name, accountNo);
  }
}

public class WebServiceCaller {
  public void CallService(ICommand command) {
    try {
      command.Execute();
    } catch (SomeBusinessException ex) {
      //handle exception
    }
  }
}

public class WebServiceCallerTest {
  public static void CallServiceTest() {
    new WebServerCaller().CallService(new TwoParameterwebServiceCall("Igor", 12345));
  }
}
Igor Zevaka
This is a strong approach I would have used in the past but I've been moving to a more functional style with my code.
ChaosPandion
This is a great dependency injection solution!
A: 

implement an IHttpModule

web.config:

<httpModules>
    ...
    <add type="Citiport.Web.Module.ErrorHandleModule" name="GlobalErrorHandler" />
    ...
</httpModules>

The Class:

public class ErrorHandleModule : IHttpModule
    {

        private static readonly ILog logger = LogManager.GetLogger("Citiport.Web.Module.ErrorHandleModule");

        public ErrorHandleModule()
        {

        }

        void IHttpModule.Dispose()
        {
        }

        void IHttpModule.Init(HttpApplication context)
        {
            context.Error += new System.EventHandler(onError);
        }

        public void onError(object obj, EventArgs args)
        {
            HttpContext ctx = HttpContext.Current;
            HttpResponse response = ctx.Response;
            HttpRequest request = ctx.Request;

            Exception exception = ctx.Server.GetLastError();
            /* handling exception here*/
        }
    }
}

refer:http://code.google.com/p/citiport2/source/browse/trunk/CitiportV2_website/App_Code/Web/ErrorHandleModule.cs

jebberwocky