A neat (?) error handling system

R

Robert Latest

Hello folks,

I'm finding myself in a situation where I write plenty of code where
"stacks" of function calls appear quite frequently, as shown below. Of
course it would be tedious to check the return value of each and every
function call, and I never really warmed to setjmp() and longjmp().

So I modified my error-prone functions to accept an additional
parameter. Before doing anything else, each function performs this
little bit of code:

void foo (int *err)
{
if (err && *err) {
++*err;
} else {
/* do stuff */
/* set *err = 1 when something fails */
}
}

So if an error has already occured elsewhere, the function increments
the value err points to and immediately returns. If an error occurs
inside the function, *err is set to 1 and the function exits. This not
only implements a convenient "fall-through" mechanism, but it also
permits localization of the function call that failed, as shown in the
example code below. I admit the errline idea is definetely taking the
concept too far because it breaks if anything but an err-aware function
call is inserted in between, but you get the drift.

Sample code:

--------------------------

int foo(blah)
{
int err = 0;
int errline;
struct command *cmd;

cmd = cmd_new(&err);
cmd_append16(cmd, CMD_START, &err); /* in my code, I have */
cmd_append32(cmd, p->feedback, &err); /* chunks like this that */
cmd_append32(cmd, p->offset_x, &err); /* span a dozen lines or */
cmd_append8(cmd, p->port, &err); /* more */
cmd_write(link, cmd, &err);
errline = __LINE__-err;
cmd_free(cmd);
if (err) {
fprintf(stderr, "Function call on line %d failed\n", errline);
}
return err ? -1 : 0;
}

-------------------------

What's the point of this posting? If you think this is a cool idea, feel
free to use it in your code. If you think it stinks, tell me why.

Thanks,
robert
 
V

Vladimir S. Oka

Robert said:
Hello folks,

I'm finding myself in a situation where I write plenty of code where
"stacks" of function calls appear quite frequently, as shown below. Of
course it would be tedious to check the return value of each and every
function call, and I never really warmed to setjmp() and longjmp().

So I modified my error-prone functions to accept an additional
parameter. Before doing anything else, each function performs this
little bit of code:

void foo (int *err)
{
if (err && *err) {
++*err;
} else {
/* do stuff */
/* set *err = 1 when something fails */
}
}

Err, if `err` is NULL, you fall through to the `else` block. If you
then encounter an error an try to set `*err` to 1. BANG!

I'd test for NULL separately, and probably abort if it happened, as
it's more likely than not to be a sign of a serious bug. Alternatively,
you could say that `err` being NULL disables the whole mechanism. The
latter is likely to be harder to maintain.
 
D

Duncan Muirhead

Err, if `err` is NULL, you fall through to the `else` block. If you
then encounter an error an try to set `*err` to 1. BANG!

I'd test for NULL separately, and probably abort if it happened, as
it's more likely than not to be a sign of a serious bug. Alternatively,
you could say that `err` being NULL disables the whole mechanism. The
latter is likely to be harder to maintain.


Also, shouldn't it be "++(*err);" ?. Further, its not inconceivable that
err gets incremented so many times that it get backs to 0. Trouble!
 
R

Robert Latest

On 20 Apr 2006 04:00:46 -0700,
in Msg. said:
Err, if `err` is NULL, you fall through to the `else` block. If you
then encounter an error an try to set `*err` to 1. BANG!

In the actual code, I of course test for that:

if (something_wrong) {
if (err) *err = 1;
....
}

robert
 
R

Robert Latest

On Thu, 20 Apr 2006 12:20:31 +0100,
in Msg. said:
its not inconceivable that
err gets incremented so many times that it get backs to 0. Trouble!

It is not, and it has been conceived. Note to self: Check and reset err
every MAX_INT function calls.

robert
 
V

Vladimir S. Oka

Robert said:
On 20 Apr 2006 04:00:46 -0700,


In the actual code, I of course test for that:

if (something_wrong) {
if (err) *err = 1;
....
}

What was the point of inviting opinions if you did not show the actual
code?
 
F

Flash Gordon

Duncan Muirhead wrote:


Also, shouldn't it be "++(*err);" ?.

Why? There is no possible ambiguity in ++*err and as far as I can see it
does the same as ++(*err)
> Further, its not inconceivable that
err gets incremented so many times that it get backs to 0. Trouble!

Depends on the code. Personally I would think that if you continue
processing for another 32767 function calls after hitting a problem you
are nor checking often enough.
 
D

Duncan Muirhead

Duncan Muirhead wrote:





Why? There is no possible ambiguity in ++*err and as far as I can see it
does the same as ++(*err)
You're right, but of course *p++ and (*p)++ are quite different, and
so I prefer to use superfluous brackets in ++(*err), to guard against
thoughtless changes.. But I shouldn't have made that point.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top