什么应该包含在最先进的错误和异常处理策略中?

时间:2009-03-31 15:31:04

标签: user-interface error-handling

我知道这是一个非常广泛的问题,但不会接受一个简短的“取决于”的答案。战略诞生于处理广泛的问题。

  1. 在设计错误和异常处理策略时,应用程序设计人员应该考虑哪些问题?

  2. 策略将如何根据软件类型(COTS,内部业务应用程序,咨询软件,游戏,托管Web应用程序,嵌入式等)而有所不同?软件类型重要吗?

  3. 道德,政治和法律问题?

  4. 关于错误处理(用户,开发人员,业务支持,管理)的各种观点。

  5. 我会探讨的一些想法:

    • 各种错误报告路径(即用户界面,日志记录,自动管理员通知)。

    • Defence in depth和健壮性(故障转移意外事件和故障安全机制,针对尚未知晓的问题进行恢复)。

    • 公平对待用户和客户(即尽量减少对软件用户和软件服务的其他人的影响)。

    我正在寻找类似的想法和概念列表。

    如果我需要进一步澄清问题并感谢所有人的贡献,请使用评论指出我!


    常见问题

    开发平台(Java,.NET,移动) - 从开发人员的角度来看肯定会对策略​​的最终实现细节产生一些影响,但从用户的角度来看则不那么明显。

    愚人节肯定不是。我被要求处理的大多数遗留系统没有明确的错误处理策略。

    这可以成为一个社区维基吗?不。这似乎是一个很好的问题,很难想出好的问题。

    这个策略是什么意思?一个长期计划,它给出了方向,重点,为错误和异常处理带来了一致性和协调性。如果一个更大的团队致力于软件,那么策略可以通过书面形式进行制定和分发。

    这似乎是重复的问题(请参阅Best practices for exception management in Java or CWhich and why do you prefer exceptions or return codes这些问题涉及错误处理的某些观点(主要是开发人员),我想更多地了解其他观点以及它们如何为整体战略做出贡献。

6 个答案:

答案 0 :(得分:6)

这里有很多可能的答案,但我会对它采取一些措施。

在设计错误和异常处理策略时,应用程序设计人员应该考虑哪些问题?

  1. 当你有多个开发人员时,应该很容易“挂钩”你的错误处理框架,否则人们就不会使用它。
  2. 明智地使用事务来维护数据一致性。我一直看到应用程序在进程中途发生故障并导致数据不一致,因为整个操作没有正确回滚。
  3. 处理异常时考虑关键性。例如,如果您有在线订购系统,并且该工作流程的一部分是将电子邮件发送给网站所有者,让他们知道已下达新订单。如果发送该电子邮件失败,用户是否会收到错误并取消整个订单?
  4. 策略将如何根据软件类型(COTS,内部业务应用程序,咨询软件,游戏,托管Web应用程序,嵌入式等)而有所不同?软件类型重要吗?

    1. 对于桌面类型或嵌入式应用程序,在调查错误报告时,记录有关环境的信息(操作系统版本,硬件,运行的其他应用程序等)非常有用。
    2. 对于企业应用和网络应用,诸如电子邮件错误通知,SMS消息传递以及与ECO工具(例如Tivoli)集成之类的东西变得非常有用。
    3. 道德,政治和法律问题?

      我唯一能想到的就是桌面应用程序 - “手机之家”类型的应用程序通常不受欢迎,特别是如果他们提交有关可能敏感的用户计算机的信息。

      有关错误处理(用户,开发人员,业务支持,管理)的各种观点。

      1. 从用户的角度来看,尝试通过设计界面以避免错误来避免错误。不要问用户可能无法回答的问题(中止,重试,任何人失败?)

      2. 从开发人员的角度来看,您需要尽可能多的信息来帮助诊断发生的事情 - 堆栈跟踪,环境信息等。

      3. 来自业务支持&从管理的角度来看,他们想知道如何处理错误(主要是在企业环境中) - 谁负责应用程序(我打电话给/ page / etc?)以及关键性和任何可能的副作用(例如,如果此批处理作业失败,那会影响哪些业务流程?)。书面文件是你的朋友。

答案 1 :(得分:4)

我来自Java背景,但我的回复也应该适用于.Net。

经验法则:

  1. 编写代码以快速失败:Hunt & Thomas;提示33
  2. 使用param检查库测试所有参数 - 这些都不是例外情况。他们滥用(记录的)API。示例:google collections Predicates
  3. 在例外条件下使用例外:[Hunt&托马斯]。提示34.不应将例外用作返回代码。
  4. 测试异常情况:异常是方法调用的后置条件。如果您无法通过测试到达那里,则不应声明异常。
  5. (For Java)关注Josh Bloch's advice(第9章全部)。 一些重要提示: 5A。抛出适合抽象的异常。 5B。争取失败的原子性。 5C。在详细消息中包含故障捕获信息(或将其封装在Exception本身中)。 5D。不要忽视例外。

答案 2 :(得分:3)

我在工作中碰到了其中的一些问题 - 虽然没有机会在那里探索它。我的想法:

在设计错误和异常处理策略时,应用程序设计人员应该考虑哪些问题?

理想的异常处理策略是完全恢复和记录错误。 catch-22 - 如果你可以做这样的事情,你不会首先在代码中写它吗?因此,它本身并不是一个“例外”,而且您的实现复杂性呈指数级增长。另一方面是自主系统领域和“自我修复软件”方法。我认为最现实的策略是始终尝试强制系统进入一致状态(即最小损坏)。你将永远被迫权衡一些东西 - 数据丢失或损坏,资源损失导致性能下降等;但是,处于一致状态会增加您在减少容量时保持运行的可能性,而不是面临完全停机。在项目团队中正式化一致状态可能意味着建立可用作重置状态的自然默认值。

策略将如何根据软件类型(COTS,内部业务应用程序,咨询软件,游戏,托管Web应用程序,嵌入式等)而有所不同?软件类型重要吗?

我认为每种类型的软件都适用于不同的审计和QoS要求,并且它反映在与停机和/或数据损坏相关的成本中;但是,总体战略是一样的。使用嵌入式,策略是将问题的外观最小化到用户并创建日志。您可以通过安静地重新启动软件(即重置状态)来实现此目的。使用托管的Web应用程序,可以转储崩溃中的会话数据以供以后分析,并且用户可以获得新会话。对于游戏(尤其是像MMORPG这样的游戏),您需要投资维护快照数据,以防止游戏玩家在服务器发生故障时失去进度。在这些实现中,服务器群集和故障转移技术也非常重要。

道德,政治和法律问题?

透明度可能是错误和异常处理中最重要的部分,它将以维护审计的形式出现。这些问题的最终结果是证明系统失效(如果发生任何附带损害)是由于一系列不可预测的事件导致设计师无法合理预见的。同样重要的是要证明现有的任何处理机制都可以通过减少损失等方式产生积极影响。在遇到灾难性故障时保持用户处于循环中也很重要(即“我的魔兽服务器在哪里去了?” ),但我的主要观点是,为了重建失败,应将透明度应用于纪律审计。

有关错误处理(用户,开发人员,业务支持,管理)的各种观点。

作为用户,错误处理应该是完全不可见的。如果服务器崩溃,我仍然希望我的银行交易按计划完成,而无需致电银行并重新运行交易。

作为开发人员,错误处理是应用程序设计中最困难的部分。由人和技术因素引起的可能出错的事物的数量,以及如何将它们分类为我们可以编写代码来处理的情况非常困难。我们依靠项目预算和管理来指导这些决定,但最终,它仍然像玩俄罗斯轮盘游戏。

对于业务支持&管理,我认为错误处理就像在软件开发阶段支付的保险,这减少了由于软件故障而不得不赔偿经历不便或中断的客户的事件。它也是软件质量和责任的衡量标准(即他们想知道哪个部门/团队/开发人员负责)。

答案 3 :(得分:3)

尽可能多地获取有关发生在开发团队中的错误的信息非常重要。如果没有用户遇到错误情况并且您可以确定某人正在检查日志文件,则日志文件很好。自动电子邮件非常适合基于服务器的应用警报消息存在问题,因为用户从不阅读它们。对我有用的一个技巧是在显示用户友好错误时将详细的错误跟踪复制到剪贴板,然后培训用户将错误跟踪粘贴到电子邮件错误报告中。等效的Web是在从服务器向开发团队发送电子邮件中的详细错误时显示友好消息。

应该有最后的日志,换句话说,当写入日志文件导致错误时会发生什么?还应该内置防止“巫师的学徒”类型的问题,其中错误处理本身锁定系统。在桌面系统上,草率的错误处理代码可能导致永无止境的消息框级联,除了杀死应用程序之外别无选择,可能会丢失进程中的数据。如果错误处理代码触发异常,则可能导致类似问题如果没有更好的选择,错误处理框架应检测错误处理错误并停止报告错误。

对于重要的批处理流程,没有什么比主动通知成功更好。如果“批量完成”电子邮件没有到达,即使错误处理是fubar,用户也会知道某些内容。

应该在边界处抓住例外情况。所有事件处理程序,公共组件函数和服务方法都应捕获发生的所有异常。在某些情况下,重新抛出异常是有道理的;例如,当在Web服务方法中捕获异常时,应抛出SOAP异常。但是,允许激活在组件边界上自动渗透是一个坏主意。

相反,在私有类方法或嵌套在组件的复杂内部过程中的方法中捕获异常通常是个坏主意。除非您可以从异常中恢复,否则在此上下文中处理异常没有意义。必须对此内部代码进行结构化,以便在出现异常时释放所有资源并回滚数据库事务。每种方法中的捕获块都是混乱的标志,使用和最后块是声音错误处理框架的标志。

请记住,异常是例外(如果您期望它们,它们将不会被称为异常!)而不是试图预测何时可能发生错误,而是集中精力来支撑组件边界。即使是不可能遇到错误的简单代码,如果它位于边界上,也应该有一个catch块。这样,当以后以意想不到的方式修改代码时,架构仍将保留。

每个组件边界可能需要不同的报告机制。对于设计为在不同上下文中运行的组件,请提供一个错误处理接口,客户端代码可以使用该接口来捕获错误消息。如果有人忘记挂钩错误处理界面,请不要忘记最后的日志。

总结一下:

  1. 获取详细的错误信息 可靠的开发团队。

  2. 陷阱错误始终位于组件边界 并且只在组件边界。

  3. 使所有代码异常安全。

  4. 不要让错误处理框架 成为问题的一部分。

答案 4 :(得分:1)

我不打算赢得赏金,但这里有一些我曾经使用并受到好评的策略:

  1. 从子组件中提取信息并将其映射到功能单元有助于我们的业务分析师和最终用户更好地理解错误

  2. 根据您所在的域名,分配业务优先级将有所帮助。

  3. 单独的错误查看器应用程序帮助我们在报告错误之前查看错误,以便我的团队可以开始修复错误。

  4. 系统级异常在没有搞乱时会更好。

  5. 错误的异步记录将有助于整体战略和设计。

  6. 创建域驱动的错误策略:意味着错误与某些业务逻辑的失败相对应。当然,大多数应该由开发人员处理,但是如果您正在处理交易引擎中的各种企业之间的消息路由,则可能会遇到某些情况。

答案 5 :(得分:0)

<opening my mind to new concepts>

  • 通过模拟纸条或地震监测滚筒打印机绘制出现的错误流程图,检查一周的进度并将其与历史数据,使用数据进行比较,并将其与预设目标进行比较。临时将长打印的长图放在墙上,并将编程团队聚集在一起进行审查。你购买他们的饮料,同时解释你的问题,这次非常具体,让程序员知道你需要什么样的策略。我打赌你,单一的coffebreak将为你的问题提供有效和令人满意的战略答案。

<closing my mind to new contepts>