【问题标题】:Exception logging and sending email异常记录和发送电子邮件
【发布时间】:2012-03-16 06:59:25
【问题描述】:

下面的异常处理方法正确吗?我发现很难记录错误并最终通过电子邮件发送日志文件。 我在哪里编写代码来记录错误并发送电子邮件?

我遇到的一个主要问题是,当在SomeClass1 中生成异常时,它会被记录两次——第二次来自SomeClass2。创建单个自定义异常类型(示例中为SomeException)并在发生时包装System.Exception 是否是个好主意?

当我们有一连串的 try-catch 相互调用时,我对如何以及何时向最终用户显示错误消息感到困惑。

class SomeClass1
{
    public static DataExtract(string sourcepath)
    {
        try
        {
            OleDbConnection oledb = new OleDbConnection();
            oledb.ConnectionString = "someconnectionstring";
            CompanyOLEDB.Open();
        }
        catch (Exception e)
        {
            throw new CustomException(e);
        }
    }
}

class SomeClass2
{
    private void SomeMethod()
    {
        try
        {
            // some code
            // some code

            SomeClass1.DataExtract()
        }
        catch (Exception e)
        {
            throw new CustomException(e);
        }
    }
}

public class CustomException : Exception
{
    protected CustomException() { }

    public CustomException(Exception e)
    {
        Log(e);
    }

    public CustomException(ExceptionType type)
    {
        this.Data.Add("Type", type);
        this.Data.Add("Message", "No message specified");
    }

    public CustomException(ExceptionType type, string message)
    {
        this.Data.Add("Type", type);
        this.Data.Add("Message", message);
    }

    public static void Log(Exception e)
    {
        System.IO.File.WriteAllText(Logfile.txt", e.ToString());
    }

    public static void Sendmail()
    {
        ExceptionMail.Sendmail();
    }
}

【问题讨论】:

标签: c# exception-handling


【解决方案1】:

下面的异常处理方法正确吗?

没有。有几个问题。这是最重要的两个。

1.您不应捕获无法处理的异常

非常重要。所有仅重新抛出或记录异常的异常块都会使代码混乱,而不会增加任何价值。仅捕获最顶层(在 web 服务、MVC 控制器、后台线程等)中的所有异常,以防止应用程序崩溃。 (但是,有时让应用程序崩溃更好)。

如果方法可以返回预期值,则处理异常。

2。始终包含原始异常

当您仅从原始异常中复制部分信息时,您正在隐藏重要的信息,以便将来能够阻止该信息。

如果你必须抓/扔其他人,你应该这样做:

public class CustomException : Exception
{
    public CustomException(string msg, Exception inner) : base(msg, inner){}
}

// 在方法中:

public void DoSomething()
{
    try
    {
        SomeCoolOp();
    }
    catch (Exception err)
    {
        throw new CustomException("Tried to allocate some cool stuff", err);
    }
}

与您的代码相比的变化:

  1. 我们以 Microsoft 推荐的方式包含原始例外
  2. 我们编写operation specific 消息,即描述发生异常时我们尝试执行的操作(而不是使用原始消息)

更多信息

我写了几篇关于异常处理的博文。

您可以先阅读:http://blog.gauffin.org/2010/11/do-not-catch-that-exception/

然后阅读其余内容:http://blog.gauffin.org/tag/exceptions/

【讨论】:

  • 如果我使用像 MVP 模式这样的层架构,最顶层是否意味着表示。您是否建议在这一层更好地捕获异常。
  • 是的。仅捕获您可以在库中处理的异常。捕获表示层内的所有其他异常。您可以使用Application.ThreadException 捕获所有未处理的异常(然后通过电子邮件发送)
  • 当我们抛出异常—— throw new CustomException("Tried to allocate some cool stuff", err)——时,它会停止程序的正常执行。这是否意味着我们无法处理异常。
  • 我不清楚你在问什么。所有异常都会阻止应用程序继续正常执行应用程序。这就是例外的目的。但是,您可以通过在最顶层捕获所有异常来防止应用程序崩溃。
  • 阅读我的文章。如果有不清楚的地方,请随时将 cmets 留在其中。企业级异常处理和微型应用程序中的异常处理没有区别。
【解决方案2】:

或许可以考虑使用类似 ELMAH 的东西,就像 Log4Net 一样,它可以配置为将错误记录到文件、数据库表或电子邮件中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 2017-05-03
    相关资源
    最近更新 更多