Skip to content

Message Error Handling

Norbert Bietsch edited this page Mar 7, 2018 · 1 revision

How To Implement Proper Error Handling

MailMergeLib is frequently used in unattended environments like task schedulers or batch jobs. This means, that properly dealing with message errors is a key requirement.

Setup Error Handling

This is very simple:

// Event raising when getting the merged MimeMessage of the MailMergeMessage has failed.
var mms = new MailMergeSender();
mms.OnMessageFailure += (mailMergeSender, messageFailureArgs) => { // do sth. useful }; 

Event arguments (MailMessageFailureEventArgs) let you observe and tackle failures during message generation:

  • The MailMergeMessage which was the argument to one of the Send methods.
  • The data source which was involved during message generation. Another argument to the Send methods.
  • An AggregateException with all reasons in detail why it was thrown, and a MimeMessage, as far as it could be generated.
  • A MimeMessage parameter which can be returned to the caller.
  • A bool parameter to decide whether the sender should raise a MailMergeMessageException

Inner exceptions of exception parameter contains AddressException, AttachmentException, EmtpyContentException, MailMergeMessageException, VariableException, ParseException) with more detailed reasons.

Options for Error Handling

When the OnMessageFailure event is fired, there are several ways to react. The most common ones are:

  • Write to failure with any necessary additional information to log file
  • Analyze the reasons for the failure, modify the MailMergeMessage and return it to the sender.
  • Create a new instance of MailMergeMessage, call a GetMimeMessage method and assign it to the MimeMessage parameter which the sender will then send.
  • Set the bool throwException to instruct the sender, whether a MailMergeMessageException shall be thrown. If true you may implement more features in a try...catch... block. Note: The MimeMessage parameter must be null in case of false, otherwise an exception will throw anyway.

Examples

Healing

var mms = new MailMergeSender { Config = ... };
mms.OnMessageFailure += (mailMergeSender, messageFailureArgs) =>
{
    lock (_locker)
    {
        // Remove the cause of the exception and return corrected values
        // Note: changes of MailMergeMessage will affect als messages to be sent
        messageFailureArgs.MailMergeMessage.PlainText = plainText.Replace("{BadVariableName}", string.Empty);
        // in production a try...catch... must be implemented
        messageFailureArgs.MimeMessage = messageFailureArgs.MailMergeMessage.GetMimeMessage(messageFailureArgs.DataSource);
        messageFailureArgs.ThrowException = false;
    }
};

Error cannot be resolved

var mms = new MailMergeSender { Config = ... };
mms.OnMessageFailure += (mailMergeSender, messageFailureArgs) =>
{
    lock (_locker)
    {
        // if you see there are too many issues:
        messageFailureArgs.ThrowException = true;
    }
};

Send the faulty MimeMessage

var mms = new MailMergeSender { Config = ... };
mms.OnMessageFailure += (mailMergeSender, messageFailureArgs) =>
{
    lock (_locker)
    {
        // if you found out it's a minor issue, so you send the faulty message
        messageFailureArgs.MimeMessage = ((MailMergeMessageException)messageFailureArgs.Error).MimeMessage;
        messageFailureArgs.ThrowException = false;
    }
};