简体   繁体   中英

How can I notify administrators of unhandled program exceptions in a DRY way?

I've got several server-side processes that run once a day. I'd like to be notified if any of them fail by email. I don't want to have to rewrite the code that catches the exception and sends the email message, since that's almost the same code every time.

I've actually already implemented an initial solution for this. I've created a class which contains the email address of the person to be notified as well as a name for the process. I'm using a delegate to allow the user to pass in a reference to a parameterless void function.

I think this will work, but is it the best way to do this? Is this even something I should be doing or is there a better way to handle errors? I thought of using C# class attributes but I'm not sure how to actually use the attribute metadata to achieve this goal.

public class ErrorNotifier
    {
        string _processName;
        string _administratorEmail;
        RunProcess _runProcess;

        public ErrorNotifier(string processName, string administratorEmail, RunProcess runProcess)
        {
            _processName= exportName;
            _administratorEmail = administratorEmail;
            _runProcess = runProcess;
        }

        public void Run()
        {
            try
            {
                _runProcess();
            }
            catch (Exception ex)
            {
                SendErrorMessage(ex);
            }
        }

        protected void SendErrorMessage(Exception ex)
        {
            SmtpClient client = new SmtpClient(serverName);
            MailMessage msg;

            string errorEmail = _administratorEmail;

            msg = new MailMessage(FormatStringStripNonAlphaNumeric(_processName) + "@business.com", errorEmail, "Error encountered during " + _processName+ " process", ex.ToString());

            client.Send(msg);
        }

        public delegate void RunProcess();
    }

Then I'm invoking it with something like this:

new ErrorNotifier(exportName,administratorEmail, ProcessToRun).Run(); 

Using a delegate is a common practice for this.

Another solution would be Aspect Oriented Programming (AOP) like PostSharp . Here is a small example how to do this: https://www.experts-exchange.com/articles/24979/DRY-Exception-Handling-with-PostSharp.html

I think the best approach in OOP is to use inheritance. Just create an abstract class with the exception handling:

public abstract class ErrorNotifier
{
    string _processName;
    string _administratorEmail;

    public ErrorNotifier(string processName, string administratorEmail)
    {
        _processName = processName;
        _administratorEmail = administratorEmail;
    }

    public abstract void RunProcess();

    public void Run()
    {
        try
        {
            RunProcess();
        }
        catch (Exception ex)
        {
            SendErrorMessage(ex);
        }
    }
}

and then make sub class for every "ProcessToRun"

public class Process1 : ErrorNotifier
{
    public override void RunProcess()
    {
        // Implement the method
    }
}

now you can simply run the sub classes:

new Process1().Run();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM