允许错误消息冒泡

时间:2013-04-23 07:45:28

标签: c error-handling

gcc(GCC)4.7.2     C89

我一直想知道从被调用函数返回错误消息时的最佳做法是什么?

在我创建的一个共享库中,我有这个功能:

/* Create directory structure */
apr_status_t dir_create(apr_pool_t *mem_pool)
{
#define SRC "test_src"

    apr_fileperms_t file_perms =
        APR_FPROT_UWRITE   |
        APR_FPROT_GWRITE   |
        APR_FPROT_WWRITE   |
        APR_FPROT_UREAD    |
        APR_FPROT_GREAD    |
        APR_FPROT_WREAD    |
        APR_FPROT_UEXECUTE |
        APR_FPROT_GEXECUTE;

    if(apr_dir_make(SRC, file_perms, mem_pool) != APR_SUCCESS) {
        LOG_CRIT("Failed to create directory");
        return FALSE;
    }

    return TRUE;
}

LOG_CRIT将显示与errno相关的相应错误消息。

在我将调用此函数的应用程序中,我有:

if(dir_create(mem_pool) != TRUE) {
    return 1;
}
LOG_INFO("Directory has been created");

例如,当上述操作失败时,它将记录如下:

[CRITICAL] dir_create:28: error [File exists] Failed to create directory

我想知道是否应该将错误消息放在调用库函数的应用程序中。或者,您是否应该在最早的时候尽快显示错误消息?

在上面的例子中,我在被调用函数中显示错误消息。当函数返回时,我只返回1来结束应用程序或执行其他操作。

另一个想法,最好是返回错误指示符,让调用函数显示错误的来源?

2 个答案:

答案 0 :(得分:2)

一些选择,越来越疯狂 - 你可能有一种适合你情况的本能;-P这更能激发你对选择的认识:

  • 尽可能多地捕获 - __FILE____LINE__errno,错误说明,正在尝试的操作,参数,结果等 - 在检测到错误的行上
  • 原则:只做来电者要你做的事;许多方法有不同的妥协:
    • 返回一个易于测试的小数据值(数字或指针),但提供一些访问函数以轻松获取上面捕获的其他信息,以便您“返回”的代码可以做任何他们喜欢的事情......
      • e.g。调用者可以取消引用该指针以获取错误详细信息,strerror() - 类似函数,调用者给出指向可打印错误消息的指针(如果调用者不需要查看该消息的含义)......
    • 立即通知调用者控制的例程,该例程可以在调用者认为合适时抑制或重定向错误;例如你的库可以提供一个指向你调用的函数的指针,调用者可以重定向 - 默认情况下可以记录到标准错误或其他一些通常可以接受的操作
    • 将您的库代码设计为#include d并使用调用者提供的预处理器宏来规定错误处理行为
    • 来自您的库的错误消息的硬编码输出,但让调用者修改可以发送的流,以便他们可以根据需要禁止它

如果使用您的库的应用程序可能想要以推测方式尝试操作(例如故障转移或事务语义),您需要更加认真地对待这类事情,特别是如果某些错误操作具有不可逆转的后果(例如某些批处理作业系统考虑如果在stderr上打印任何内容,则失败的工作 - 但从程序的角度来看,库函数可能不构成失败,或者弹出图形错误对话框会使无人操作失败。

答案 1 :(得分:1)

我建议您在最低级别记录错误消息,就像您在此处所做的那样。如果您需要访问errno,这一点尤为重要,否则当您获得更高级别的功能时,这可能会发生变化。在此级别,我会尽可能地将错误消息作为技术和特定信息。

根据库函数的返回值,您的应用程序代码可能会采取一些操作(例如,它可能会显示一个弹出窗口,提供人类可读的错误描述,或者它可以写入stderr )。如果您愿意,通常可以在尽可能高的级别 - UI级别完成。