My DAL doesn't handle exceptions and it will be propagated up to the calling method in the presenter classes where the exception will be handled.
I'm using a single handler called ExecutAction(Action action) so I'm catching exceptions in one place rather than repeating in every method.
At the moment, I'm not logging errors. Just alert the user for an action and try to keep the system alive if possible.
When showing messages to users, Presenters will use a static class called MessagingService. (ShowErrorMessage()). So that I can customize all massage boxes in one place.
private void Search()
{
ExecutAction(() =>
{
var info = _DataService.GetByACNo(_model.AccountNumber);
if (info != null)
{
_Model = info ;
this.SetViewPropertiesFromModel(_Model, _View);
}
else
{
MessageBox.Show ("Bank account not found");
}
});
}
private void ExecutAction(Action action)
{
try
{
action();
}
catch (NullReferenceException e) { MessagingService.ShowErrorMessage(e.Message); }
catch (System.Data.SqlTypes.SqlTypeException e) { MessagingService.ShowErrorMessage(e.Message); }
catch (System.Data.SqlClient.SqlException e) { MessagingService.ShowErrorMessage(e.Message); }
}
}
Should I include general exception handler to this, to be able to handle any unforeseen exceptions?
Also could you show me a better way to handle showing messages than using a static?
Does use of lambda statements in every method call (ExecutAction(() =>) degrade code readability?
When showing user messages how to show a custom message like "Check the server connection" etc. first and then if the user wants more information (like StackTrace / technical details) he /she could press a button like More Info which is in the MessageBox dialog?
I agree with jeffrey about trying to incorporate IoC for your message service. You could define an abstract base presenter class that has a dependency on an interface for your message service. The base class would be responsible for handling the delegate execution + exception logging.
public interface IMessageService
{
void ShowErrorMessage(Exception e);
}
public abstract class PresenterBase
{
private readonly IMessageService _messageService;
public PresenterBase(IMessageService messageService)
{
this._messageService = messageService;
}
protected void ExecuteAction(Action action)
{
try
{
action();
}
catch (Exception e) { this._messageService.ShowErrorMessage(e); }
}
}
public class SearchPresenter: PresenterBase
{
public SearchPresenter(IMessageService messageService)
: base(messageService)
{
}
public void Search()
{
this.ExecuteAction(() =>
{
//perform search action
});
}
}
Regarding your question about catching all exeptions. Unless you are doing something special for specific types of exceptions, I would suggest just handling all the same. The example I provided passes the exception to the message service so that the formatting specifics can be handled by your message service.
If you have not yet incorporated any sort of IoC container, you can always start by using the interface injection and then passing the instance explicitly from the child class constructor.
public class SearchPresenter: PresenterBase
{
public SearchPresenter()
: base(new SomeMessageService())
{
}
...
}
This is at least removes the static dependency and is not too dificult to swap out later if you ever introduce an IoC container.
I think your approach is good enough for your work. Wrapping logics by ExecuteAction is an acceptable way to me. As another option, I might use AOP for centralized exception handling in practice.
Also, I might use a MessagingService resolved from dependency injection container rather than a static one.
Regarding how to display the error, that's totally depend on your business purpose. For example, you could simply log the error and tell the user "something's wrong", or show them the complete stacktrace including the environment information so they could simply copy & paste in the email.
Related
I'm writing a class that works with an API Client object that sometimes becomes corrupted and has to be recreated from inside the object that uses it. What is the best way to do this using Dependency Injection? I'm hesitant to call the DI framework from inside the class since it makes my code dependent on it.
public class MyObject
{
protected IMyAPIClient Client { get; set; }
public MyObject(IMyAPIClient client)
{
Client = client;
}
protected async Task<ReturnType> Run<ReturnType>(Func<Task<ReturnType>> action, int attempt = 1)
{
try
{
return await action();
}
catch(Exception exception)
{
Client = await GetNewClient();
if(attempt > MAX_ATTEMPTS)
{
throw new Exception($"Failed {attempt} times", exception);
}
return await Run(action, attempt++);
}
}
protected async Task<IMyAPIClient> GetNewClient()
{
// what to do here?
}
}
One solution that I came up with was to implement IMyAPIClient in a class that knows the type of IMyAPIClient and recreates it, thus circumventing the DI framework. I wonder if this is sensible or if there is a better way to do it?
I would first try to fix the problems with the ApiClient. Using workarounds for buggy code is rarely a good idea, but might some times be required for third party code. If the problem is in third party code it might also be advisable to put it in a separate process, otherwise you cannot know if failures have some unexpected side-effects.
To create new objects I would suggest injecting a factory of some kind. Exactly how this is done would depend on the DI/IoC framework. Simplest might be a Func<IMyAPIClient>, but an alternative would be an explicit factory-class. You can chose if the factory should use the IoC container to construct the object, or just construct it directly. Also, some IoC framework will handle factories in some special way, while others might require factories to be registered just like everything else. Check the documentation for your framework to see how factories should be managed.
I would also recommend moving the restart logic to a decorator if possible. That way it is separated from the usage, and should be more flexible in case there are multiple users, or the logic needs to be updated. However, registering decorators can be a bit tricky to ensure they are working correctly, but this will also depend on your IoC framework.
I solved the problem by creating a factory class that creates the IMyAPIClient.
This way I can handle the dependency injection in this factory class without making other code dependent on the DI framework.
public class MyObject
{
protected IMyAPIClientFactory ClientFactory { get; set; }
public MyObject(IMyAPIClientFactory clientFactory)
{
ClientFactory = clientFactory;
Client = clientFactory.CreateClient();
}
protected async Task<ReturnType> Run<ReturnType>(Func<Task<ReturnType>> action, int attempt = 1)
{
try
{
return await action();
}
catch(Exception exception)
{
Client = await clientFactory.CreateClient();
if(attempt > MAX_ATTEMPTS)
{
throw new Exception($"Failed {attempt} times", exception);
}
return await Run(action, attempt++);
}
}
}
I have a part of my program that sends me an email and/or a push message to my iphone when something occurs. This is done through calls to two seperate WCF services using MSMQ. I followed this guide (model 4.0) in order to make it generic and test friendly. I like the generic channel creation, but my question is wether the proxies and channel factories are really closed/disposed correctly, or if this will blow up when it reaches a 10000 user environment (which it eventually will). The code works perfectly in my 50 user test environment.
Therefore, please review the following code:
Service Proxy
public class ServiceProxy<TChannel> : IServiceProxy<TChannel> where TChannel : ICommunicationObject
{
private readonly TChannel InnerChannel;
public ServiceProxy(TChannel innerChannel)
{
this.InnerChannel = innerChannel;
}
public void Execute(Action<TChannel> operation)
{
try
{
operation(InnerChannel);
InnerChannel.Close();
}
catch (CommunicationException)
{
InnerChannel.Abort();
}
catch (TimeoutException)
{
InnerChannel.Abort();
}
catch (Exception)
{
InnerChannel.Abort();
throw;
}
}
public TResult Execute<TResult>(Func<TChannel, TResult> operation)
{
TResult result = default(TResult);
try
{
result = operation(InnerChannel);
InnerChannel.Close();
}
catch (CommunicationException)
{
InnerChannel.Abort();
}
catch (TimeoutException)
{
InnerChannel.Abort();
}
catch (Exception)
{
InnerChannel.Abort();
throw;
}
return result;
}
}
Service Proxy Factory
public class ServiceProxyFactory : IServiceProxyFactory
{
public IServiceProxy<TChannel> GetProxy<TChannel>(string endpointName) where TChannel : ICommunicationObject
{
var factory = new ChannelFactory<TChannel>(endpointName);
return new ServiceProxy<TChannel>(factory.CreateChannel());
}
}
Making a service call (without return type for simplicity)
public class MessageSender : IMessageSender
{
private const string PushServiceEndpoint = "PushEndpointName";
private const string MailServiceEndpoint = "MailEndpointName";
private readonly IServiceProxyFactory ServiceProxyFactory;
public MessageSender()
{
ServiceProxyFactory = new ServiceProxyFactory();
}
public void NotifyMe(*some args*)
{
ServiceProxyFactory.GetProxy<MailServiceChannel>(MailServiceEndpoint)
.Execute(a => a.SendEmail(*some args*));
}
The questions are:
Should I close the ServiceProxy after the Execute?
Is it wise to create a ChannelFactory every time I call GetProxy(), and should this ChannelFactory then be closed again if so?
Is it really performance friendly to generate a ServiceProxy for every call? (it seems really heavy to me, but maybe someone can prove me wrong).
I left the interfaces out from this post, but they are really simple, and this whole setup with proxies and interfaces works really well with unit and integration testing.
I hope some of you coding wizards have an opinion about this, and will share this.
Thanks in advance!
The main performance impact has the creation of a ChannelFactory.
Creating ChannelFactory instances incurs some overhead because it involves the following operations:
Constructing the ContractDescription tree
Reflecting all of the required CLR types
Constructing the channel stack
Disposing of resources
https://msdn.microsoft.com/en-us/library/hh314046%28v=vs.110%29.aspx
WCF team has implemented caching for ClientBase<TChannel> class, it is suitable when you have auto generated proxy classes.
As you are using pure ChannelFactory you have to be careful about creating factories it on each call in order to have a better performance.
A good solution would be to implement caching of ChannelFactory<TChannel> your own (there is a good idea on how to do that). So at the end in your ServiceProxyFactory instead of having new ChannelFactory<TChannel>(endpointName); you should use cached instances like CachedChannelFactory<TChannel>.GetInstance().
Edit: There is another good article written by Michele Leroux Bustamante, that explains when To Cache or Not to Cache
I have a system which fundamentally is used to resolve exceptions and output a CSV on demand which details every resolved item. Each day, there will be new exceptions which need to be dealt with. I have a POST method for this in my controller:
[HttpPost]
private ActionResult Resolve(ExceptionViewModel modifiedExceptionViewModel, string currentFilter)
{
// resolve database records...
return RedirectToAction("Index", "Exceptions");
}
I have had a new requirement however, the user wants the system to identify when the last outstanding has been resolved and then automatically output the CSV to the file share, rather than having to go and do this manually.
I firstly created a method for checking whether or not that was the last exception, and called this WasLastException(); I knew that I could just wrap this in an IF statement and on true call a method I have called OutputMasterFileCsv(); but before doing this I thought I would try out delegates/events for the first time which has led me to a similar result but has also raised a few questions.
Some background to my application
This is an Entity Framework Code First MVC web application that is making use of using Unity DI, I have wrapped all my repository calls in an ProcessDataService class in my core layer, which has an interface IProcessDataService that is being registered with Unity.
This is how I have tried to add my event:
Controller's constructor
public ExceptionsController(IProcessDataService service)
{
_service = service; //publisher
//event for delegate
OutputService outputService = new OutputService(_service); //subscriber
_service.LastException += outputService.OnLastException;
}
Output Service
public void OnLastException(object source, EventArgs e)
{
// output the CSV
}
Process Data Service
public delegate void LastExceptionEventHandler(object source, EventArgs args);
public class ProcessDataService : IProcessDataService
{
private readonly IExceptionRepository _exceptionRepository;
public ProcessDataService(IExceptionRepository evpRepo)
{
_exceptionRepository = evpRepo;
}
public event LastExceptionEventHandler LastException;
public void OnLastException()
{
if (LastException != null)
LastException(this, EventArgs.Empty);
}
}
New Resolve method in the Controller
[HttpPost]
private ActionResult Resolve(ExceptionViewModel modifiedExceptionViewModel, string currentFilter)
{
// resolve database records...
if(_service.WasLastException())
{
//raise the event
_service.OnLastException();
}
return RedirectToAction("Index", "Exceptions");
}
This all works well, however I feel like I am not using delagates and events in the right place here somehow, Instead of calling the OnLastException() above and making use of the event, why wouldn't I just simply call _service.OutputMasterFileCsv(); which is already located in my ProcessDataService class?
I believe this has something to do with loose coupling but I dont fully understand what the benefits of this actually are, or am I completely off the mark with all this...?
I thought I would give it ago anyway while I had the chance and hopefully learn something new. If anyone with abit more experience could step in and provide some guidance it would be greatly appreciated as I am a little lost now.
As you are correctly pointing out, using events in this way does not make much sense:
if(_service.WasLastException())
{
//raise the event
_service.OnLastException();
}
You can fix this by making IProcessDataService expose a ResolveException action, and moving the resolving logic from the controller to the service:
[HttpPost]
private ActionResult Resolve(ExceptionViewModel modifiedExceptionViewModel, string currentFilter)
{
// make needed preparations...
_service.ResolveException(...prepared parameters...);
return RedirectToAction("Index", "Exceptions");
}
Then, inside the ProcessDataService.ResolveException method check
if you are currently processing the last exception, and raise the LastException event.
public class ProcessDataService : IProcessDataService
{
//...
public ResolveException(...prepared parameters...) {
// resolve an exception and set lastException
if(lastException) {
this.OnLastException();
}
}
// notice the private modifier
private void OnLastException()
{
if (LastException != null)
LastException(this, EventArgs.Empty);
}
}
This way the data processing service simply notifies the outside world when the last exception is processed. The service has no idea if anyone cares or does something when this happens. The controller knows even less. Only the output service contains processing logic for last exceptions.
With that said, the real power of events lies in the fact that there can be many subscribers, with each subscriber performing its own tasks without knowing anything about the other subscribers. So, you could for instance add another event handler to say, send an email to a supervisor saying that all the exceptions for the day have been resolved.
What matters is that in this case you would not need to modify the controller or other services to account for this newly introduced email sending functionality.
You have decoupled the controller from the service and service from storage. That is fine. But I don't really understand the sense of the event LastException in the ProcessDataService. This is already decoupled by interface IProcessDataService, why to use event?
Another think I don't understand is where is the last exception?
If you want to decouple outputService from ProcessDataService, you can do it like:
public ProcessDataService(IExceptionRepository evpRepo, IOutputService outputService)
{
_exceptionRepository = evpRepo;
_outputService = _outputService;
}
public void ProcessLastException()
{
_outputService.Command() //or whatever suitable name you for your method
}
And in controller:
if(_service.WasLastException())
{
//call service
_service.ProcessLastException();
}
Or even more simple add some method for processing last exception to IProcessDataService.
There are more ways how to inject dependency. You have injected the dependency into constructor and that is why, you don't need the event for decoupling.
I don't think I am even asking this right but here it goes.
I have a .NET CF app that displays a datagrid of info. This app is connected by TCP Sockets to a Central Server that will periodically broadcast out data.
How do I get my datagrid on my ShellForm to update. Feels wrong to have a reference to my ShellForm in my DAL where the Socket stuff is happening.
Would I use a Delegate or Async Callback? Just looking for a little guidance. Thanks!
The DAL can just publish an Event, and then the GUI can subscribe to it.
The reference (and dependency) will be from the GUI to the DAL.
Watch your thread-safety as well.
I'd suggest that your UI shouldn't know anything about your DAL at all. What I'd do for this would be to create an intermediate "presenter" class that watches the DAL and then can notify the UI, either via an event, callback or whatever.
I would most likely create a presenter class that implements INotifyPropertyChanged, which would allow you to directly watch the event or to data bind to the property that you're using to fill your grid. The presenter would also handle marshaling to the UI context, so neither the UI or the DAL would have to worry about it.
Some sort-of pseudo code might look like this. Bear in mind I have all sorts of infrastructure bits in my code, so this is not likely to just compile, but it should give you a flavor of how I'd attack the problem.
class PointPresenter : INotifyPropertyChanged
{
private IDataService DAL { get; set; }
protected Control EventInvoker { get; private set; }
public PointPresenter()
{
// get your DAL reference however you'd like
DAL = RootWorkItem.Services.Get<IDataService>();
EventInvoker = new Control();
// this is required to force the EE to actually create the
// control's Window handle
var h = EventInvoker.Handle;
}
protected void RaisePropertyChanged(string propertyName)
{
try
{
if (m_disposed) return;
EventInvoker.BeginInvokeIfRequired(t =>
{
try
{
PropertyChanged.Fire(this, propertyName);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
});
}
catch (ObjectDisposedException)
{
// if the Form to which we're sending a message is disposed,
// this gets thrown but can safely be ignored
}
catch (Exception ex)
{
// TODO: log this
}
}
public int MyDataValue
{
get { return DAL.Data; }
set
{
if (value == MyDataValue) return;
DAL.Data = value;
RaisePropertyChanged("MyDataValue");
}
}
}
Is there a better way to catch exceptions? I seem to be duplicating a lot of code. Basically in every controller I have a catch statement which does this:
try
{
Do something that might throw exceptions.
}
catch (exception ex)
{
Open database connection
Save exception details.
If connection cannot be made to the database save exception in a text file.
}
I have 4 controllers and around 5-6 actions methods in each controller which is a lot of code duplication. How can I trim down on the amount of line in the try catch statement above?
You could make use of Extension methods here.
Create an extension method in a new class.
public static class ExtensionMethods
{
public static void Log(this Exception obj)
{
// log your Exception here.
}
}
And use it like:
try
{
}
catch (Exception obj)
{
obj.Log();
}
You don't need to put try/catch blocks on every method. That's tedious and painful! Instead you can use the Application_Error event of Global.asax for logging the exceptions. The code below is the sample implementation which can be used to catch exceptions that occur in your web application.
protected void Application_Error(object sender, EventArgs e)
{
var error = Server.GetLastError();
if (!string.IsNullOrWhiteSpace(error.Message))
{
//do whatever you want if exception occurs
Context.ClearError();
}
}
I would like also to stress that "Handled exception" especially trying to put try/catch blocks on most methods is one of the "Top 3 silent performance killers for IIS / ASP.NET apps" as explained in this blog http://mvolo.com/fix-the-3-high-cpu-performance-problems-for-iis-aspnet-apps/
What you are trying to do is called a cross-cutting concern. You are trying to log any error that happens anywhere in your code.
In ASP.NET MVC cross-cutting concerns can be achieved by using Filters. Filters are attributes that can be applied globally, to a controller or to a method. They run before an action method executes or after it.
You have several types of filters:
Authorization filters, they run to check if the user is allowed to access a resource.
Action filters, these run before and after an action method executes.
Result filters, these can be used to change the result of an action method (for example, add some extra HTMl to the output)
Exception filters run whenever an exception is thrown.
In your case, you are looking for exception filters. Those filters only run when an exception happens in in an action method. You could apply the filter globally so it will automatically run for all exceptions in any controller. You can also use it specifically on certain controllers or methods.
Here in the MSDN documentation you can find how to implement your own filters.
Personally, since I greatly dislike try/catch blocks, I use a static Try class that contains methods that wrap actions in reusable try/catch blocks. Ex:
public static class Try {
bool TryAction(Action pAction) {
try {
pAction();
return true;
} catch (Exception exception) {
PostException(exception);
return false;
}
}
bool TryQuietly(Action pAction) {
try {
pAction();
return true;
} catch (Exception exception) {
PostExceptionQuietly(exception);
return false;
}
}
bool TrySilently(Action pAction) {
try {
pAction();
return true;
} catch { return false; }
}
// etc... (lots of possibilities depending on your needs)
}
I have used a special class in my applications that is called ExceptionHandler, in the class that is static I have some methods to handle application's exceptions. It gives me an opportunity to centralize exception handling.
public static class ExceptionHandler
{
public static void Handle(Exception ex, bool rethrow = false) {...}
....
}
In the method you can log the exception, rethrow it, replace it with another kind of exception, etc.
I use it in a try/catch like this
try
{
//Do something that might throw exceptions.
}
catch (exception ex)
{
ExceptionHandler.Handle(ex);
}
As Wouter de Kort has rightly stated in his answer, it is cross-cutting concern, so I've put the class in my Application Layer and have used it as a Service. If you defined the class as an interface you would be able to have different implementations of it in different scenarios.
Also you can use Singleton pattern:
sealed class Logger
{
public static readonly Logger Instance = new Logger();
some overloaded methods to log difference type of objects like exceptions
public void Log(Exception ex) {}
...
}
And
Try
{
}
Catch(Exception ex)
{
Logger.Instance.Log(ex);
}
Edit
Some peoples don't like Singleton for reasonable grounds.instead of singleton we can use some DI:
class Controller
{
private ILogger logger;
public Controller(ILogger logger)
{
this.logger = logger;
}
}
And use some DI library that will inject one instance of ILogger into your controllers.
I like the answers suggesting general solutions, however I would like to point out another one which works for MVC.
If you have a common controller base (wich you should anyways, it's a Best Practice IMO). You can simply override the OnException method:
public class MyControllerBase : Controller
{
protected override void OnException(ExceptionContext filterContext)
{
DoSomeSmartStuffWithException(filterContext.Exception);
base.OnException(filterContext);
}
}
Then simply inherit your normal controllers from your common base instead of Controller
public class MyNormalController : MyControllerBase
{
...
If you like this you can check out the Controller class for other handy virtual methods, it has many.
In ASP .NET MVC you can implement your own HandleErrorAttribute to catch all the exceptions that occur in all controllers:
public class CustomHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
var ex = filterContext.Exception;
// Open database connection
// Save exception details.
// If connection cannot be made to the database save exception in a text file.
}
}
Then register this filter:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomHandleErrorAttribute());
}
}
And of-course call the register method on application start-up:
public class MvcApplication : HttpApplication
{
protected override void OnApplicationStarted()
{
// ...
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
// ...
}
}
Wouter de Kort has already explained the concept behind this in his answer.