Search code examples
capi-designlibrary-design

Designing public error codes in C for a library


A design issue I'm trying to solve is what is the flexible way to make client to be able to handle errors that may occur when calling to a library functions. I see 2 approaches:

I. To put all errors that my be raised by any library functions in a public separate header file, e.g. lib_errors.h:

#define APP_ERR_OBJECT_TOO_SMALL 1 /* The object is too small */

#define APP_ERR_HOST_UNREACHABLE 2 /* Host is not reachable */

#define APP_ERR_UNKNOWN          3 /* Unknown error */

And include it in all the public header files of the library.

header1.h:

#include "lib_errors.h"

/**
 * -1 - on error 
 *      error_code is set to APP_ERR_OBJECT_TOO_SMALL the buf is too small
 *      error_code is set to APP_ERR_UNKNOWN in case of unknown error
 */ 
int hdr1_drain(void *buf, size_t sz, int *error_code);

header2.h:

#include "lib_errors.h"

/**
 * -1 - on error 
 *      error_code is set to APP_ERR_HOST_UNREACHABLE if the host is unreachable
 *      error_code is set to APP_ERR_UNKNOWN in case of unknown error
 */ 
int hdr2_connect(char *add, int *error_code);

The problem I see: All errors the library can raise will be included in each of the header files even those that the header itself does not raise.

II. To define a header-specific errors in each header files:

header1.h:

#define HDR1_OBJECT_TOO_SMALL 1
#define HDR1_UNKNOWN          2

header2.h

#define HDR2_HOST_UNREACHABLE 1
#define HDR2_UNKNOWN          2

The problem I see: The amount of code duplicate increases with the number of common errors. All of the common errors have to be duplicated in each public header files.

So I'm currently confused which one to choose. Probably there is another way to approach the design issue. The first approach seems to be closer to the POSIX errno.


Solution

  • You can combine the two approaches. Put all the common errors in one header, and then the application-specific errors in the app header.

    lib_errors.h:

    #define ERR_UNKNOWN 1
    ...
    #define LIBERR_LAST 100
    

    header1.h:

    #include "lib_errors.h"
    
    #define HDR1_OBJECT_TOO_SMALL (LIBERR_LAST + 1)
    ...
    

    header2.h:

    #include "lib_errors.h"
    
    #define HDR2_HOST_UNREACHABLE (LIBERR_LAST + 1)
    ...