捕获所有异常以进行详细的日志记录 - 优点和缺点

时间:2014-07-04 10:09:44

标签: c# exception logging load try-catch

我正在编写一个保存和加载系统,将游戏对象保存为JSON兼容格式并加载回来。保存对象很好,相当万无一失。但是,我正在努力使加载过程更加防弹,更容易让我发现错误。显然,当我从JSON文件加载数据时,所有内容都是从字符串转换而来,可能会出现各种用户错误。

每个对象加载方法都包含类似的内容---

public void Load() 
{
    try
    {
        // Deserialize..
        // Potential for all kinds of exceptions, invalid casts, missing info, etc..
        // For eg:

        bool active = data.GetField("active").Value<bool>();

        // GetField() throws an exception if the field doesn't exist.
        // Value<T>() throws an exception if it's an invalid cast, etc.
    }
    catch(Exception e)
    {
        // ..and those exceptions get caught and logged here.
        Logger.LogError(e.ToString, this);
    }
}

捕获对象中所有异常的好处之一Load方法是当&#39; LogError()&#39;使用对象作为参数调用,如图所示,它将突出显示IDE层次结构中违反错误的对象(无论哪一个),以便快速找到带有错误的对象并对其进行调试。脚本或保存的数据。

这是抛出和捕获异常的适当用法,还是我应该实现更好的设计模式?

谢谢你的时间, 萨姆

2 个答案:

答案 0 :(得分:1)

关于different but close总是有很多catching the exceptions意见,但对于您的任务,给定的方法简单而可行。我建议您做的唯一事情就是让异常冒泡:

catch(Exception e)
{
    // ..and those exceptions get caught and logged here.
    Logger.LogError(e.ToString, this);
    throw;
}

记录是一个好主意,但如果加载失败,您的程序应该怎么做?只需将其注销并继续?可能是这种情况,但这种加载方法看起来像程序的重要组成部分。它看起来不像是一些背景工作 - 可能失败或工作 - 我不关心。好吧,它是你的计划,我不知道要求或背景 - 只是我的意见。

您应该将异常处理作为基础的主要原则是:仅在可以对其执行操作的时间和地点捕获异常(重试,在方法中获取一些相关的当前数据...) ,以其他方式抓住他们 在调用层次结构中尽可能高(在主循环或全局异常处理程序中 - 越高越好,这意味着要复制的异常处理更少)。如果您不能做任何可以保证程序状态一致性的例外情况 - 请不要抓住它。

理想情况下,所有课程都应该能够适应失败 - 如果失败,他们要么失败,要么不做任何事情或将状态恢复正常。最理想的解决方案是,如果他们在例外情况下回滚任何行动的副作用 - 类似交易的行为。但在现实生活中,这是一个难以实现的目标。

另外,如果您不喜欢类似的try-catch构造,以便在代码中的任何地方进行日志记录(它们很重要,但它们不做任何实际工作 - 它们的存在并不是必需的。了解主要工作流程),您可以尝试一些Aspect Oriented Programming technologies

答案 1 :(得分:0)

你的问题仍然缺少很多基本的东西,例如什么样的对象&#34;数据&#34;是,它是一个字符串,类或任何其他类型。

只要您的代码处理可能发生的所有可能异常,捕获异常就永远不会对性能有益。 仍然可能存在抛出异常的情况。

我建议检查字段而不是直接调用具有该名称的字段,例如,

bool active = data.HasField("active") ? data.GetField("active").Value<bool>() : false;

另外,在catch中作为常见场景更好地传递异常对象而不是e.Tostring()

类似的东西:

Logger.LogError(e, this);

总之,它实际上取决于应用程序的应用程序或者对需求的要求。 在Web应用程序中,我通常创建HttpModule来记录异常,这样我就不必在代码中的任何地方编写catch块。

public class ExceptionModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.Error += new EventHandler(OnError);
        }

        private void OnError(object sender, EventArgs e)
        {
            //write logging exception logic.
        }
}