Reputation: 171
A good suggestion on how to handle errors within a Client can be found here.
Copying here for easy access:
MyServiceClient myServiceClient = new MyServiceClient();
try
{
documents = myServiceClient.GetDocuments();
// More code that isn't useful including here ...
myServiceClient.Close();
}
catch (TimeoutException exception)
{
MessageBox.Show(exception.Message, "Timeout error", MessageBoxButtons.OK, MessageBoxIcon.Error);
myServiceClient.Abort();
}
catch (FaultException<ServiceErrorDetails> error)
{
MessageBox.Show(error.Detail.Message, "Service error", MessageBoxButtons.OK, MessageBoxIcon.Error);
myServiceClient.Abort();
}
catch (CommunicationException exception)
{
MessageBox.Show(exception.Message, "Communication error", MessageBoxButtons.OK, MessageBoxIcon.Error);
myServiceClient.Abort();
}
Now the problem I am having with this solution is that my Proxy contains many many methods. Easy to understand I would rather not want to add this huge try/catch statement around all my method calls.
Instead, I thought it could be a good idea to add the error handling from within MyServiceClient() class.
But the question is how to do that without polluting all the Methods here again with this try/catch statement?
How would you approach that?
Upvotes: 1
Views: 348
Reputation: 1196
You could try encapsulating the try/catch logic in a handler class as follows:
public static class Example
{
public static void ExecuteExample()
{
var serviceClient = new ServiceClient();
var documents = ProxyErrorHandler.Execute(serviceClient, serviceClient.GetDocuments);
}
}
public static class ProxyErrorHandler
{
public static void Execute(ServiceClient serviceClient, Action actionToExecute)
{
Execute(serviceClient, () =>
{
actionToExecute();
return true;
});
}
public static T Execute<T>(ServiceClient serviceClient, Func<T> functionToExecute)
{
try
{
return functionToExecute();
}
catch (Exception exception)
{
ShowException(serviceClient, exception);
return default;
}
}
public static Task ExecuteAsync(ServiceClient serviceClient, Func<Task> actionToExecute)
{
return ExecuteAsync(serviceClient, async () =>
{
await actionToExecute();
return true;
});
}
public static async Task<T> ExecuteAsync<T>(ServiceClient serviceClient, Func<Task<T>> functionToExecute)
{
try
{
return await functionToExecute();
}
catch (Exception exception)
{
ShowException(serviceClient, exception);
return default;
}
}
private static void ShowException(ServiceClient serviceClient, Exception exception)
{
string title;
var message = exception.Message;
switch (exception)
{
case TimeoutException:
title = @"Timeout error";
break;
case FaultException<ServiceErrorDetails> faultException:
title = @"Service error";
message = faultException.Detail.Message;
break;
case CommunicationException:
title = @"Communication error";
break;
default:
ExceptionDispatchInfo.Throw(exception);
// Unreachable
throw new Exception();
}
MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
serviceClient.Abort();
}
}
Upvotes: 2