1

How to do that if there is any error (anyone) to capture this error and write to a log ..

Recently a client changed the password webmaster (email used to authenticate messages sent) And this meant that the system was no longer able to send emails. The problem is that the error was not discovered days later.

Would you like a way to catch this error and save the message (email) and a log error, how?

In controller

new MailController(_subsidiaryService).PedidoOrcamentoEmail(model).DeliverAsync();

in MailController

public EmailResult PedidoOrcamentoEmail(BudgetViewModel model)
{
    From = string.Format("{0} <{1}>", model.Name, model.Email);
    To.Add("Site <" + ConfigurationManager.AppSettings["toEmail"] + ">");

    var subInfo = (from s in _subsidiaryService.Repository.Query()
                   where s.ID == model.SubsidiaryID
                   select new
                              {
                                  s.Title,
                                  s.District
                              }).SingleOrDefault();
    ViewData["SubsidiaryTitle"] = subInfo.Title;
    ViewData["SubsidiaryDistrict"] = subInfo.District;

    Subject = "[Pedido de Orçamento] " + model.Name;
    return Email("PedidoOrcamentoEmail", model);
}
    protected override void OnException(System.Web.Mvc.ExceptionContext filterContext)
            {
// This is not executed             
base.OnException(filterContext);
            }

As a test, I put in an invalid password email webmaster (used for shipping)

ridermansb
  • 10,779
  • 24
  • 115
  • 226
  • you can use http://logging.apache.org/log4net/ to log the exception and write to disk or send an email. – marcoaoteixeira Feb 22 '13 at 19:14
  • @Slaks nice last time I did this I had to write my own HttpModules (although they aren't that hard) – Conrad Frix Feb 22 '13 at 19:15
  • @SLaks I'm using it, but this is an error beyond the error log will log **the message**. To log the message need an event to be triggered if an error occurs while sending the email. – ridermansb Feb 22 '13 at 19:17
  • Have a look at this question, a couple of the answers might help: http://stackoverflow.com/questions/5737695/asp-net-mvc-onexception-try-catch-required – Jack Feb 22 '13 at 19:42
  • @Jack The problem is that sending email is async. `.DeliverAsync();` When the password webmaster (e-mail address used for shipping) is wrong, do not even know if an exception is thrown. And another detail, I would not do this for whole application, only when sending e-mail – ridermansb Feb 22 '13 at 20:23
  • You can try changing DeliverAsync() to Deliver() just to see if it will raise an exception then. And maybe wrap your `DeliverAsync()` statement in a `try/catch` to see if that raises anything. `OnException` is only called when an unhandled exception occurs in an action. I haven't looked through all of the ActionMailer source but it looks like there's no callback on the `DeliverAsync` method and not much in the way of error handling. – Jack Feb 22 '13 at 22:03

1 Answers1

1

Create a custom MailSender that inherits from the default MailSender and wrap the calls to the base methods in try..catch blocks. Then you can do anything with the exception when it occurs.

public class CustomMailSender : SmtpMailSender
{
    private readonly ILog _log = LogManager.GetCurrentClassLogger();
    public CustomMailSender() { }
    public CustomMailSender(SmtpClient client) : base(client) { }

    public new void Send(MailMessage mail)
    {
        try
        {
            base.Send(mail);
            //Do some logging if you like
            _log.Info(....)

        }
        catch (SmtpException e)
        {
            //Do some logging 
            var message = mail.RawMessageString();
            _log.Error(message, e);
            // rethrow if you want...
        }
    }

    public new void SendAsync(MailMessage mail, Action<MailMessage> callback)
    {
        ... similar ...
    }
}

In your MailController the CustomMailSender is used like this:

public MailController() {
    MailSender = new MyCustomMailSender();
}
hydr
  • 408
  • 3
  • 10
  • In my case I use the package [ActionMailer](http://nuget.org/packages/ActionMailer/) to send emails. Do not call any method directly to send emails, this is left to the ActionMailer. How do I use this class? – ridermansb May 06 '13 at 17:43
  • Have a look here: https://bitbucket.org/swaj/actionmailer.net/wiki/Home#!advanced-stuff. "Advanced Stuff" tells how to use a custom MailSender. Basically you add some extra behaviour to the class that is responsible for sending the mails. – hydr May 14 '13 at 19:49