There's no good answer.
The first thing to do is to divide your code into "pure functions" and
"procedures". A pure function shuffles bits, a prodeucre shuffles bits
and does IO.
A pure function can only fail in three circumstances, it's called with
invalid parameters, there's an internal error in its coding, or it
runs out of memory.
A procedure can fail in these circumstances, and also because of a
hardware problem, because the user provides erroneous or even
malicious data, because hardware is functioning but is overwhelmed by
the demands of the prodecure, or because of missing resources such as
non-existent files.
So let's take the situations one by one. If you have invalid
parameters, that normally indicates a programming error in calling
code. The rare exception is when caller can't reasonably be expected
to check the parameters for validity - e.g. a statistical procedure
might fail when the numbers have a distribution that becomes less like
a bell curve when you take means of a sample. Caller can't reasonably
be expected to check for that condition. If caller can't be expected
to check the parameters, an "abormal" result must be passed back as
part of the normal flow control of the program. If caller can, there's
not much point in shuting the error back up to a buggy caller. You
need to abort the program with an error message if it can be aborted,
suppress the error if abortion isn't an option.
Internal error - difficult. Your own code is buggy. There's no real
answer to this situation.
Out of memory - if it can reasonably be expected that the function
will run out of memory, shunt up an "out of memory" condition to
caller. If basically this can't happen (you need to store one filename
dynmaically ona amchine with 4GB of memory), abort with an out of
memory message.
Hardware problems: is in once in a blue moon, or can it reasonably be
expected? If it's once in a blue moon, simply report an IO error and,
usually, terminate. If it's expected, you will need to know how to
code round the expected harware failures.
Bad user data - usually you should assume that the user is a hacker
trying to make your program malfunction. Should be normal control path
of the program, and reported up to caller.
Overhelmed hardware - very difficult. If it will take a whole day to
write results to disk, is this acceptable or must be abort? It's often
not easy to answert these questions, or anticipate them. The file
might be quite small, the disk hardware very busy.
Missing resources - happens all the time. Treat as normal flow control
of program.
So generally the strategy is to treat so-called error conditions as
normal flow control, and pass the error condition up to caller. So
they're not really errors at all. The exception is errors caused by
programming mistakes. It's dangerous to pass an error back up to a
buggy caller. Normally you want to assert fail, which gives the
compiler the chice between reporting and aborting, or siliently
suppressing the error.
Centralised error systems mean that code will break if you try to move
it to a different project.
--
Basic Algorithms - massive compendioum of C programming resources
http://www.malcolmmclean.site11.com/www