P
petschy
hello all,
i'm writing network message processors for a server app. after
dispatching, the processor function is called for the given message
type. the tokens in the message are validated, checked against the
server state, and if everything is ok, an operation is perfomed, and
optionally a reply is sent back. in some cases of invalid input, an
error message is sent back.
with the naive approach this leads to deeply nested if statements
(complex messages), where the innermost true block does the actual
operation and sends the reply. else branches might send the error
reply. this structure is hard to oversee and maintain, so i was
searching for better ways.
A)
bool error = true;
const char* reason = "?";
do {
....
if (invalid input that needs reply) {
reason = "FOO";
break;
}
if (invalid input that doesn't need reply) {
return;
}
...
} while ((error = false));
if (error) {
send_err_reply(reason);
} else {
send_reply();
}
this is ok only when there are no validators in for/while/case
constructs. also, if called functions throw exceptions, there should be
a try/catch block, too. this brings us to plan b:
B)
try {
...
if (invalid input that needs reply) {
throw "FOO";
}
if (invalid input that doesn't need reply) {
return;
}
...
send_reply();
} catch (const char* e) {
send_err_reply(e);
} catch (...) {
// catch other exceptions from called functions and either ignore
them or send back an error
}
i'm not completely satisfied with this approach, since it uses
throw/catch in the same function, but i haven't yet found an equally
simple but more efficient solution, considering that throwing/catching
has some overhead in time/space compared to other flow control
mechanisms.
any ideas?
cheers, p
i'm writing network message processors for a server app. after
dispatching, the processor function is called for the given message
type. the tokens in the message are validated, checked against the
server state, and if everything is ok, an operation is perfomed, and
optionally a reply is sent back. in some cases of invalid input, an
error message is sent back.
with the naive approach this leads to deeply nested if statements
(complex messages), where the innermost true block does the actual
operation and sends the reply. else branches might send the error
reply. this structure is hard to oversee and maintain, so i was
searching for better ways.
A)
bool error = true;
const char* reason = "?";
do {
....
if (invalid input that needs reply) {
reason = "FOO";
break;
}
if (invalid input that doesn't need reply) {
return;
}
...
} while ((error = false));
if (error) {
send_err_reply(reason);
} else {
send_reply();
}
this is ok only when there are no validators in for/while/case
constructs. also, if called functions throw exceptions, there should be
a try/catch block, too. this brings us to plan b:
B)
try {
...
if (invalid input that needs reply) {
throw "FOO";
}
if (invalid input that doesn't need reply) {
return;
}
...
send_reply();
} catch (const char* e) {
send_err_reply(e);
} catch (...) {
// catch other exceptions from called functions and either ignore
them or send back an error
}
i'm not completely satisfied with this approach, since it uses
throw/catch in the same function, but i haven't yet found an equally
simple but more efficient solution, considering that throwing/catching
has some overhead in time/space compared to other flow control
mechanisms.
any ideas?
cheers, p