【问题标题】:How to design extendable error codes?如何设计可扩展的错误代码?
【发布时间】:2013-04-25 18:28:30
【问题描述】:

更新: 这里的错误码并不是这样一个函数的返回值。实际上,我不是在讨论使用异常或错误代码进行错误处理。我试图弄清楚,使用什么模式来组织错误。 我真正在做的就是在 Windows 蓝屏上显示错误代码。回到很早以前,当你的 Windows 崩溃时,你会在蓝屏上看到一个错误代码,使用该代码你可以通过查找 MS 的文档来弄清楚发生了什么。 在我的系统中,有许多插件由不同的人贡献,他们可能彼此不认识。如果我允许他们定义他们的错误代码。这主要是两个插件的错误代码可能会冲突

================================================ =================================================

我想设计一个可扩展的错误代码系统,允许插件定义自己的错误代码。 基本思路是:

  1. 系统有一系列保留的错误代码
  2. 插件可以选择系统未使用的范围,然后在该范围内创建其错误代码。但是,问题是插件彼此不认识(因为插件可能由不同的人编写并根据用户的喜好安装到系统中)。因此它们的错误代码范围可能会发生冲突。

这个要求有什么好的做法吗?我用谷歌搜索了很多,但令我惊讶的是,很少有文章谈论在生产软件中设计错误代码。大多数帖子都关注异常与错误代码。

而且,有没有什么好的模式可以显示产品中的错误,用户可以弄清楚发生了什么? 我的基本想法是向用户显示包含错误代码、描述和详细信息的错误。用户可以点击错误代码,然后我会告诉他正确的解决方案

【问题讨论】:

  • 你不应该设计一个使用错误代码的系统,除非你有某种限制。错误代码没有丰富的异常,通常会在其他领域推广糟糕的设计,
  • 为什么这标记为 java 和 python ...在 python 中它的所有异常 ...
  • 没意义,这么多不同的程序使用这么多不同的库。普通用户甚至可能不了解编程中的类型。一个好的程序员会很好地记录和测试代码,但如果用户输入错误,当错误不可避免时也会有备份,这一切都在程序员的手中
  • 谢谢你们。请查看我的更新@PopCatalin
  • 谢谢你们。请查看我的更新@JoranBeasley

标签: java python design-patterns error-handling software-design


【解决方案1】:

不知道你正在构建的插件系统是做什么的......

插件是否应该负责向宿主应用程序提供这些信息?为什么不让对插件执行操作的结果包含这些项目呢?这样,您的主机应用程序就不会关心插件特定的实现细节,只关心某些事情是否正常......

const int OP_SUCCESS = 0;

// structure returned for plugin ops
struct OperationResponse {
    int code; // any other value than OP_SUCCESS is plugin-defined
    string message; // operation optional message, even if success
    // other fields
};

所以每次调用插件都会这样做:

OperationResponse r = plugin.DoOperation();

if (r.code != OP_SUCCESS) {
    // do something with r.message and other fields
}

【讨论】:

  • 仍然,如果错误代码以插件提供程序和插件名称为“前缀”,例如一个你不会真正冲突的命名空间。例如:error com.foo.plugins.XYZ.0039 表示 foo.com 的 XYZ 插件错误 #0039。
【解决方案2】:

对于您的应用程序抛出的每个异常,您都将其插入数据库,您的错误代码是该记录的 id,这就是用户看到的。显然,相同的异常得到相同的 id。您需要的插件信息存储在数据库中

【讨论】:

  • 谢谢,但这并不能解决冲突。假设插件 A 使用代码 10 表示 xxx 异常,插件 B 不知道 A 因为它们是由不同的人编写的,B 也使用 10 表示 yyy 异常。
  • 他们不会。 A 和 B 只会抛出一个异常,你的应用程序的最外层将有一个异常处理机制,如果它还没有,它将把它插入到一个 db 中,并将记录 id(错误代码)返回给用户。如果 A 和 B 碰巧抛出了完全相同的异常,并且具有相同的堆栈跟踪,那么您必须解决相同的错误。通常两段代码会抛出不同的异常/堆栈跟踪。因此,A 或 B 或任何其他插件都不必“记录”它们的代码,它们将被插入到这个数据库中,就是这样
  • 感谢您的解释。但这对我不起作用。例如,A 和 B 都抛出 IOException,其中 A 的原因是无法写入文件,而 B 的原因是网络连接被拒绝。在这种情况下,错误代码是相同的,但它们对用户来说确实是不同的错误。 @OscarRyz
  • 堆栈跟踪会非常不同,甚至错误消息也会非常不同,因此它们将使用不同的 id。错误代码的问题是它们不可扩展,但如果您坚持只为插件分配一个 3 - 4 个字母的代码并让他们使用他们想要的任何错误代码。因此,如果插件 A 用于“Awesome Advanced whateever”,则为它们分配插件代码 AAW ...它们的代码范围将是 AAW-001 到 AAW-999(或 9999 或 99999),而插件 B 可以是 BAR-864
  • 我对你最后将如何处理这个问题很感兴趣,所以如果你可以(我相信它会在未来对其他人有益)添加你自己的答案关于你是如何做到的在末尾。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 2016-09-19
  • 1970-01-01
相关资源
最近更新 更多