> Sford wiki > Internal error handling

See my blog for the justifications for this approach.

Here's some code that should be in everybody's Unix C programs. It's newly-refined, so don't get on my case if you see some of my code that doesn't have it in this form. This code is Public Domain; use freely without restriction.

/* Minimal but very useful error handling. */
#define WCHK(cond_expr) do { \
  if (!(cond_expr)) { \
    fprintf(stderr, "%s:%d, Warning, expected '%s' to be true (%s)\n", \
      __FILE__, __LINE__, #cond_expr, strerror(errno)); \
  }  \
} while (0)

#define ECHK(cond_expr) do { \
  if (!(cond_expr)) { \
    fprintf(stderr, "%s:%d, Error, expected '%s' to be true (%s)\n", \
      __FILE__, __LINE__, #cond_expr, strerror(errno)); \
    abort(); \
  }  \
} while (0)

These macros are basically a better assert(). In addition to just printing the file/line/conditional, it also prints the human-readable string for errno, which might not be applicable for a particular usage, but it's useful enough when it *is* applicable that I just always include it. WCHK() is for warnings (i.e it prints the message but continues execution). ECHK() is for fatal errors (i.e. calls abort() which dumps core). Both should be used for conditions that "should never happen". A failure typically indicates a software bug that needs to be tracked own and fixed.

They should be used like assert(), passing in a boolean expression, typically a conditional. For example:

char *buf = malloc(65536);  ECHK(buf != NULL);

FILE *state_fd = fopen("statefile", "r");  WCHK(x_fd != NULL);  /* we ship initial state file, should never fail. */
if (state_fd == NULL) {
    create_statefile();
}
FILE *state_fd = fopen("statefile", "r");  ECHK(x_fd != NULL);

The WCHK() macro should *rarely* be used. Most errors that have reasonable recovery measures are actually user errors. User errors should have much better error messages that tell the user what he did wrong and what he should do to correct it.

Note that the macros above are different from the ones in my blog. The use of errno and abort() is not always appropriate for complicated software systems. The blog version is more generally applicable to a variety of system-level error handling frameworks. But for Unix tools, the macros above are usually fine.

But don't just include these macros in your program and then forget about them! As described in my blog, the point of these is to make liberal use of sanity checks in your code, but do so in a way that doesn't significantly degrade your code's readability. DOWN WITH UNCHECKED RETURN STATUSES AND NEEDLESSLY INDENTED CODE! (Hmm ... better re-think my career dream as sloganeer.)

Retrieved from "http://wiki.geeky-boy.com/w/index.php?title=Internal_error_handling"